带Spring的log4j2 JDBC appender

时间:2016-09-11 09:40:09

标签: spring jdbc log4j2 appender

可以使用通过调用和方法定义的池化连接工厂来设置Log4j2 JDBC appender(参见log4j2 Appenders):

 <ConnectionFactory class="net.example.db.ConnectionFactory" method="getDatabaseConnection" />

使用Spring我已经定义了一个提供池化连接的数据源:

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${db_driver_class}" />
    <property name="url" value="${db_jdbc_url}" />
    <property name="username" value="${db_username}" />
    <property name="password" value="${db_password}" />
    <property name="initialSize" value="10" />
    <property name="maxActive" value="100" />
    <property name="maxIdle" value="50" />
    <property name="minIdle" value="10" />
    <property name="validationQuery" value="select 1" />
    <property name="testOnBorrow" value="true" />

我想将Spring连接池用于JDBC appender。知道如何做到这一点?

感谢

拉​​兹

1 个答案:

答案 0 :(得分:1)

我想要创建一个3步骤的解决方案:

  1. 在spring上下文中定义一个bean,提供对数据的访问         源
  2. 构建提供bean的bean的实现         期望的连接。
  3. 构建一个可由log4j JDBC appender访问的静态包装器。
  4. 第一步 - bean声明:

        <bean id="springConnection" class="com.dal.entities.SpringConnection" scope="singleton">
        <property name="dataSource" ref="myDataSource" />
    

    第二步 - bean实现 - 也很简单:

    class SpringConnection {
    
    private DataSource dataSource;
    
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    Connection getConnection() throws Exception {
        return dataSource.getConnection();
    }
    

    }

    第三部分 - 使用静态方法的包装器 - 有点复杂:

    public class SpringAccessFactory  {
    
    private final SpringConnection springCon;
    private static ApplicationContext context;
    
    private interface Singleton {
        final SpringAccessFactory INSTANCE = new SpringAccessFactory();
    }
    
    private SpringAccessFactory()  {
    
        this.springCon = context.getBean(SpringConnection.class);
    }
    
    public static Connection getConnection() throws Exception {
        return Singleton.INSTANCE.springCon.getConnection();
    }
    
    public static void setContext( ApplicationContext context) {
        SpringAccessFactory.context = context;
    }
    

    }

    然而,到目前为止,我发现了两个问题:

    • 在开始使用记录器之前,需要初始化spring上下文并将其发送到包装器(SpringAccessFactory.setConetxt)
    • 在程序早期初始化spring上下文可能会触发@PostConstruct方法(如果存在),在你打算这样做之前......