简体   繁体   English

带有 Spring 的 log4j2 JDBC appender

[英]log4j2 JDBC appender with Spring

Log4j2 JDBC appender can be setup using a pooled connection factory that is defined using calls and method (see log4j2 Appenders ):可以使用使用调用和方法定义的池化连接工厂来设置 Log4j2 JDBC appender(请参阅log4j2 Appenders ):

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

Using Spring I have already a defined datasource that is providing a pooled connection :使用 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" />

I would like to use the the Spring connection pool for the JDBC appender.我想将 Spring 连接池用于 JDBC appender。 Any idea how can this be done ?知道怎么做吗?

thanks谢谢

Raz拉兹

I mange to create a 3-steps solution :我设法创建一个 3 步解决方案:

  1. Define a bean in spring context that provide access to a data source在 spring 上下文中定义一个 bean 来提供对数据源的访问
  2. Build an implementation of the bean that provide the desired connection.构建提供所需连接的 bean 的实现。
  3. Build a static wrapper that can be accessed by the log4j JDBC appender.构建一个可由 log4j JDBC appender 访问的静态包装器。

1st step - bean declaration :第一步 - bean 声明:

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

the 2nd step - bean implementation - is also simple :第二步 - bean 实现 - 也很简单:

class SpringConnection {

private DataSource dataSource;

public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
}

Connection getConnection() throws Exception {
    return dataSource.getConnection();
}

} }

the 3rd part - wrapper with static method - is a bit more complex:第三部分 - 静态方法的包装器 - 有点复杂:

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;
}

} }

There are - however - 2 issues I found so far:到目前为止,我发现了两个问题:

  • You need to initialize the spring context and send it into the wrapper (SpringAccessFactory.setConetxt) before you start using the logger在开始使用记录器之前,您需要初始化 spring 上下文并将其发送到包装器(SpringAccessFactory.setConetxt)中
  • initializing spring context early in program may trigger @PostConstruct methods (if any exists), before you plan to do so.....在您计划这样做之前,在程序早期初始化 spring 上下文可能会触发 @PostConstruct 方法(如果存在).....

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM