1. 采用 JNDI 注入的方式
Coframe采用主应用的数据源,主应用(SpringBoot)数据源可采用任意实现,如:Druid、C3p0、commons-dbcp等。
应用代码中直接在 JNDI 中注入 DataSource:
java
/*
如下为 统一 数据源,将SpringBoot 初始化的数据源,注入到 JNDI 中,并设置 default 的数据源名称
Coframe在 user-config.xml 中配置了采用 JNDI 的方式获取数据源,可直接获取到注入的。
*/
try {
// JNDI 环境配置,采用 DummyContextFactory 测试可通过
final Properties environment = new Properties();
environment.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.primeton.workflow.commons.transaction.DummyContextFactory");
// 设置
final JndiTemplate jndiTemplate = JNDIDataSourceProvider.getDefaultJndiTemplate();
jndiTemplate.setEnvironment(environment);
// 内部搜索名称,有 java:comp/env/ 的前缀, Coframe 会根据不同服务器,选择不同实现,这里这样搜索实现
String prefix = StringUtils.trimToNull(ServerTypeAwareManager.getCurrentServerTypeAware().getJNDIPrefix());
if (prefix == null) {
prefix = "";
}
jndiTemplate.bind(prefix + BFTConstants.DEFAULT_DS_NAME, dataSource);
} catch (Exception e) {
log.info("JNDI Bind Datasource Error.", e);
}
在 user-config.xml 中可配置采用 JNDI 数据源:
xml
<group name="default">
<configValue key="Jndi-Name">default</configValue>
<configValue key="Jdbc-Type"/>
<configValue key="Transaction-Isolation">ISOLATION_DEFAULT</configValue>
<configValue key="Test-Connect-Sql">SELECT count(*) from EOS_UNIQUE_TABLE</configValue>
<configValue key="Retry-Connect-Count">-1</configValue>
<configValue key="Driver-Encoding">UTF-8</configValue>
<configValue key="Db-Encoding">UTF-8</configValue>
</group>
Cofram 启动后,可正确获取数据源。
2.采用Coframe数据源,应用中可不配置
也可采用 Coframe 中实现的数据源,Coframe中唯一实现是 C3P0。
可在 Coframe 的 spring.xml 配置文件中输出DataSource
xml
<!-- 门面模式, 用 Coframe 中的 DataSource,不需要再初始化一个连接了 -->
<bean id="dataSource" class="com.primeton.bft.bftconsole.config.CoFrameDataSourceProxy">
<constructor-arg index="0" value="DefaultDataSource" />
<property name="dataSourceGroupName" value="default" />
<property name="dataSource" ref="DefaultDataSource" />
</bean>
CoframeDataSourceProxy 是一个 Spring FactoryBean:
java
@Slf4j
@Setter
public class CoFrameDataSourceProxy implements FactoryBean,
InitializingBean, DisposableBean {
/**
* 全局静态,保存共有变量
*/
private static final Map<String, Object> OIBJ_CACHED = new ConcurrentHashMap<>(4);
protected String dataSourceGroupName = "default";
private String dataSourceName;
/**
* 数据源,c3p0
*/
protected DataSource dataSource;
/**
* 构造方法注入代理
* @param dataSourceName
*/
public CoFrameDataSourceProxy(String dataSourceName) {
this.dataSourceName = dataSourceName;
}
@Override
public void afterPropertiesSet() throws Exception {
if(dataSource == null) {
// 从 全局 中获得
DataSource ds = (DataSource)OIBJ_CACHED.get(dataSourceName);
// 赋值
this.dataSource = ds;
} else {
// 数据源非空,放到 全局中
Object lookup = OIBJ_CACHED.get(dataSourceName);
if(lookup == null && dataSource != null) {
// 尚未在 jndi 绑定
OIBJ_CACHED.put(dataSourceName, dataSource);
logger.info("proxy datasource pushed to proxy...");
}
}
// 检验数据源
Preconditions.checkNotNull(dataSource, "can not find dataSource instance.");
try(Connection connection = dataSource.getConnection();) {
logger.info("get proxy datasource success...");
} catch (Exception ignored){}
}
@Override
public void destroy() throws Exception {
try {
// Spring 停止时调用
Method closeMethod = dataSource.getClass().getDeclaredMethod("close");
if (closeMethod != null) {
closeMethod.invoke(dataSource);
}
} catch (Exception ignored) {}
}
@Override
public Object getObject() throws Exception {
return dataSource;
}
@Override
public Class getObjectType() {
return DataSource.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
主应用SpringBoot 中可不配置数据源,且可正常获得数据源。
Coframe 相关的类(重要):
com.eos.common.connection.mbean.DataSourceConfigHandler
com.eos.internal.system.IServerTypeAware
com.primeton.ext.common.connection.datasource.DataSourceCache
com.primeton.ext.common.connection.datasource.DataSourceFactory
com.primeton.common.connection.impl.datasource.JNDIDataSourceProvider
com.primeton.ext.common.connection.datasource.C3P0DataSourceProvider