Vesta发号器源码解析——IdServiceFactoryBean
这个类是IdService的工厂类
import部分
主要包括几个部分,具体内容如下注释
//数据库连接和操作
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
//不同类型的发号器的实现方式
import com.robert.vesta.service.impl.IdServiceImpl;
import com.robert.vesta.service.impl.provider.DbMachineIdProvider;
import com.robert.vesta.service.impl.provider.IpConfigurableMachineIdProvider;
import com.robert.vesta.service.impl.provider.PropertyMachineIdProvider;
//对外服务的统一接口
import com.robert.vesta.service.intf.IdService;
//日志相关部分
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//Spring框架适配
import org.springframework.beans.factory.FactoryBean;
//异常
import java.beans.PropertyVetoException;
类定义部分
这部分本身没什么,主要是实现了Spring框架内的FactoryBean接口
这个接口是一个简单工厂模式的接口,生产单一类型的对象,最终要注册到Spring的BeanFactory中的,但是实现这个接口的类在注册到Spring的BeanFactory后,不像其他的类注册后是暴露自己,这个类暴露的是FactoryBean,举个例子:
在spring配置文件中配置了名字 myFcBean 的一个类型,该类型是 FactoryBean 的实现类。那么通过
BeanFactory.getBean(“myFcBean”) 返回的并不是这个类型本身的对象,而是调用这个对象的getObject方法的返回值。
在当前这个类中,返回的是IdService
public class IdServiceFactoryBean implements FactoryBean<IdService> {
属性字段部分
//日志记录
protected final Logger log = LoggerFactory
.getLogger(IdServiceFactoryBean.class);
//提供的机器id持有模式枚举类,包括配置文件,IP地址,数据库
//TODO zookeeper是比较理想的方式
public enum Type {
PROPERTY, IP_CONFIGURABLE, DB
} ;
//机器ID生成的类型
private Type providerType;
//IP地址
private String ips;
//数据库相关信息
private String dbUrl;
private String dbName;
private String dbUser;
private String dbPassword;
//机器ID
private long machineId;
//生成方式 0-嵌入式 1-中心服务器发布模式 2-Rest发布模式 3-保留未用共四种
private long genMethod = -1;
//类型 0 最大峰值型 1最小粒度型
private long type = -1;
//版本 默认0 1未用
private long version = -1;
//Idservice持有
private IdService idService;
方法部分
初始化方法:
public void init() {
//配置的产生类型不能为空
if (providerType == null) {
//为空记录日志后抛出非法参数异常
log.error("The type of Id service is mandatory.");
throw new IllegalArgumentException(
"The type of Id service is mandatory.");
}
//根据类型判断返回和初始化的具体实现类
switch (providerType) {
case PROPERTY:
//配置文件初始化,需要提供machineID作为参数
idService = constructPropertyIdService(machineId);
break;
case IP_CONFIGURABLE:
//根据IP进行初始化,参数提供IP地址
idService = constructIpConfigurableIdService(ips);
break;
case DB:
//构建基于db的bean,参数为DB相关参数
idService = constructDbIdService(dbUrl, dbName, dbUser, dbPassword);
break;
}
}
获取Idservice
没什么可说的,就是返回idservice
public IdService getObject() throws Exception {
return idService;
}
用配置文件进行构造
private IdService constructPropertyIdService(long machineId) {
//记录日志
log.info("Construct Property IdService machineId {}", machineId);
//初始化Provider,设置好machineID
PropertyMachineIdProvider propertyMachineIdProvider = new PropertyMachineIdProvider();
propertyMachineIdProvider.setMachineId(machineId);
//初始化对应类型的实现
IdServiceImpl idServiceImpl;
//类型校验,如果为-1按照默认构造,否则按照给定类型构造
if (type != -1)
idServiceImpl = new IdServiceImpl(type);
else
idServiceImpl = new IdServiceImpl();
//设置初始化好的Provider
idServiceImpl.setMachineIdProvider(propertyMachineIdProvider);
//初始化生成方式和版本
if (genMethod != -1)
idServiceImpl.setGenMethod(genMethod);
if (version != -1)
idServiceImpl.setVersion(version);
//初始化执行
idServiceImpl.init();
//返回
return idServiceImpl;
}
利用IP初始化
private IdService constructIpConfigurableIdService(String ips) {
//记录日志
log.info("Construct Ip Configurable IdService ips {}", ips);
//初始化Provider
IpConfigurableMachineIdProvider ipConfigurableMachineIdProvider = new IpConfigurableMachineIdProvider(
ips);
//初始化对应类型的实现
IdServiceImpl idServiceImpl;
//类型校验,如果为-1按照默认构造,否则按照给定类型构造
if (type != -1)
idServiceImpl = new IdServiceImpl(type);
else
idServiceImpl = new IdServiceImpl();
//设置初始化好的Provider
idServiceImpl.setMachineIdProvider(ipConfigurableMachineIdProvider);
//初始化生成方式和版本
if (genMethod != -1)
idServiceImpl.setGenMethod(genMethod);
if (version != -1)
idServiceImpl.setVersion(version);
//初始化执行
idServiceImpl.init();
//返回
return idServiceImpl;
}
DB模式的初始化
private IdService constructDbIdService(String dbUrl, String dbName,
String dbUser, String dbPassword) {
//记录日志
log.info(
"Construct Db IdService dbUrl {} dbName {} dbUser {} dbPassword {}",
dbUrl, dbName, dbUser, dbPassword);
//数据源连接池P0的连接池
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//驱动类
String jdbcDriver = "com.mysql.jdbc.Driver";
//初始化驱动类
try {
comboPooledDataSource.setDriverClass(jdbcDriver);
} catch (PropertyVetoException e) {
log.error("Wrong JDBC driver {}", jdbcDriver);
log.error("Wrong JDBC driver error: ", e);
throw new IllegalStateException("Wrong JDBC driver ", e);
}
//设置数据源属性
//最小连接池大小
comboPooledDataSource.setMinPoolSize(5);
//最大连接池大小
comboPooledDataSource.setMaxPoolSize(30);
//测试连接有效的时间间隔
comboPooledDataSource.setIdleConnectionTestPeriod(20);
//最大空闲时间
comboPooledDataSource.setMaxIdleTime(25);
//关闭失败后对数据源进行block的机制
//如果设置为True表示pool向数据库请求连接失败后标记整个pool为block并close,
//就算后端数据库恢复正常也不进行重连,客户端对pool的请求都拒绝掉
comboPooledDataSource.setBreakAfterAcquireFailure(false);
//当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出
//SQLException,如设为0则无限期等待。单位毫秒,默认为0
comboPooledDataSource.setCheckoutTimeout(3000);
comboPooledDataSource.setAcquireRetryAttempts(50);
comboPooledDataSource.setAcquireRetryDelay(1000);
//构建数据库连接字符串
String url = String
.format("jdbc:mysql://%s/%s?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true",
dbUrl, dbName);
//设置JDBC相关信息
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(dbUser);
comboPooledDataSource.setPassword(dbPassword);
//使用jdbcTemplate
JdbcTemplate jdbcTemplate = new JdbcTemplate();
//懒初始化
jdbcTemplate.setLazyInit(false);
//设置数据源
jdbcTemplate.setDataSource(comboPooledDataSource);
//初始化db的provider
DbMachineIdProvider dbMachineIdProvider = new DbMachineIdProvider();
//设置对应的jdbcTemplate
dbMachineIdProvider.setJdbcTemplate(jdbcTemplate);
//初始化provider
dbMachineIdProvider.init();
IdServiceImpl idServiceImpl;
//按照类型初始化IdService实现类,如果type为-1,按照默认初始化
if (type != -1)
idServiceImpl = new IdServiceImpl(type);
else
idServiceImpl = new IdServiceImpl();
//设置Provider
idServiceImpl.setMachineIdProvider(dbMachineIdProvider);
//设置生成方式
if (genMethod != -1)
idServiceImpl.setGenMethod(genMethod);
if (version != -1)
idServiceImpl.setVersion(version);
idServiceImpl.init();
//返回
return idServiceImpl;
}
其他相关方法,主要是一些字段的get和set
//返回对应类型dService的类类型
public Class<?> getObjectType() {
return IdService.class;
}
//是否单例,固定返回true
public boolean isSingleton() {
return true;
}
//返回Provider的类型
public Type getProviderType() {
return providerType;
}
//设置Provider类型
public void setProviderType(Type providerType) {
this.providerType = providerType;
}
//返回MachineId
public long getMachineId() {
return machineId;
}
//设置MachineId
public void setMachineId(long machineId) {
this.machineId = machineId;
}
//获取IP
public String getIps() {
return ips;
}
//设置Ip
public void setIps(String ips) {
this.ips = ips;
}
//获取Db的URL
public String getDbUrl() {
return dbUrl;
}
//设置DB的URL
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
//获取DB的名字
public String getDbName() {
return dbName;
}
//设置DB的名字
public void setDbName(String dbName) {
this.dbName = dbName;
}
//DBUser获取
public String getDbUser() {
return dbUser;
}
//设置DBUSer
public void setDbUser(String dbUser) {
this.dbUser = dbUser;
}
//获取密码
public String getDbPassword() {
return dbPassword;
}
//设置密码
public void setDbPassword(String dbPassword) {
this.dbPassword = dbPassword;
}
//获取生成方式
public long getGenMethod() {
return genMethod;
}
//设置生成方式
public void setGenMethod(long genMethod) {
this.genMethod = genMethod;
}
//获取类型
public long getType() {
return type;
}
//设置类型
public void setType(long type) {
this.type = type;
}
//获取版本
public long getVersion() {
return version;
}
//设置版本
public void setVersion(long version) {
this.version = version;
}
网友评论