Skip to content

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