log4j пользовательский приложение jdbc, источник данных

Чтобы использовать источник данных в моем приложении log4j, я написал собственный приложение. Приложение пытается получить источник данных как компонент Spring. Однако приложение не может получить bean-компонент. Я использую следующие технологии: mybatis, tomcat и spring.

Мои файлы log4j выглядят так:

#configuring the requestinterceptor  
log4j.category.com.db.wscis.core.web.interceptor=INFO, sql
log4j.appender.sql=com.db.wscis.core.util.appender.CustomJDBCAppender
log4j.appender.sql.sql=INSERT INTO LOGS VALUES ('%x', current_timestamp ,'%C','%p','%m')
log4j.appender.sql.layout=org.apache.log4j.PatternLayout

Код для настраиваемого приложения выглядит следующим образом:

public class CustomJDBCAppender extends org.apache.log4j.jdbc.JDBCAppender {

 protected java.sql.Connection getConnection() throws java.sql.SQLException {

         if(connection == null) {
             org.springframework.jdbc.datasource.DataSourceTransactionManager dstm = (org.springframework.jdbc.datasource.DataSourceTransactionManager) ExternalBeanFactory.getBean("txManager");
             if(dstm==null) throw new java.sql.SQLException("dstm is null");
             System.out.println("here");
             connection = DataSourceUtils.getConnection(dstm.getDataSource());
             return connection;
         } else{
             return connection;
         }
     }

    /* protected void execute(String sql) throws java.sql.SQLException {

         Connection con = null;
         Statement stmt = null;

         try {
             con = getConnection();
             stmt = con.createStatement();
             stmt.executeUpdate(sql);
             con.commit();
         } catch (SQLException e) {
            if (stmt != null)
                 stmt.close();
            closeConnection(con);
            throw e;
         } 
       }
     */
     protected void closeConnection() throws java.sql.SQLException {
             if (connection != null && !connection.isClosed())
                   connection.close();
     }
}

Фабричный класс External Bean выглядит так:

/* 
 */    
package com.db.wscis.core.util;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

public class ExternalBeanFactory implements BeanFactoryAware {

    /**
     * Bean factory instance.
     */
    private static BeanFactory beanFactory;

    /**
     * Sets beanfactory.
     * 
     * @param beanFactory
     *            BeanFactory object
     * 
     * @see org.springframework.beans.factory.BeanFactoryAware#
     *      setBeanFactory(org.springframework.beans.factory.BeanFactory)
     * @exception BeansException
     *                if failed to set factory
     */
    public final void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    /**
     * DO NOT use this method in the application classes. This is meant to be
     * used by the framework level classes ONLY!!!!
     * 
     * Finds from bean from the factory.
     * 
     * @param beanName
     *            Name of the bean
     * @return bean object
     */
    @Deprecated
    public static final Object getBean(final String beanName) {
    //  if(beanFactory==null) System.out.println("Bean factory is null");
        return beanFactory.getBean(beanName);
    }

    public final Object getBeanInstance(final String beanName) {
        return beanFactory.getBean(beanName);
    }
}

Теперь, когда сервер tomcat запускается, я предполагаю, что он пытается инициализировать log4j. Таким образом, он вызывает метод getConnection в настраиваемом приложении. Этот inturn вызывает ExernalFactory.getBean (), однако свойство beanfactory в External BeanFactory еще не инициализировано.
Трассировка стека ошибок выглядит следующим образом:

SEVERE: Error configuring application listener of class com.db.wscis.core.web.context.FWContextLoaderLis
java.lang.NullPointerException
        at com.db.wscis.core.util.ExternalBeanFactory.getBean(ExternalBeanFactory.java:64)
        at com.db.wscis.core.util.appender.CustomJDBCAppender.getConnection(CustomJDBCAppender.java:27)
        at org.apache.log4j.jdbc.JDBCAppender.execute(JDBCAppender.java:215)
        at org.apache.log4j.jdbc.JDBCAppender.flushBuffer(JDBCAppender.java:289)
        at org.apache.log4j.jdbc.JDBCAppender.append(JDBCAppender.java:186)
        at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
        at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.
        at org.apache.log4j.Category.callAppenders(Category.java:206)
        at org.apache.log4j.Category.forcedLog(Category.java:391)
        at org.apache.log4j.Category.log(Category.java:856)
        at org.apache.commons.logging.impl.Log4JLogger.info(Log4JLogger.java:176)
        at com.db.wscis.core.web.context.FWContextLoaderListener.<init>(FWContextLoaderListener.java:34)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.j
        at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
        at java.lang.Class.newInstance(Class.java:374)
        at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:140)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4888)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
        at java.util.concurrent.FutureTask.run(FutureTask.java:166)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:724)

Скажите, пожалуйста, что я делаю не так и как мне получить экземпляр компонента источника данных в моем классе appender.


person TimeToCodeTheRoad    schedule 04.09.2014    source источник
comment
Можете поправить форматирование? Спасибо!   -  person admdrew    schedule 04.09.2014
comment
@anmdrew: вы можете помочь решить проблему?   -  person TimeToCodeTheRoad    schedule 05.09.2014
comment
@TimeToCodeTheRoad Какая версия Spring? Вы используете его сервлет или его список в своем web.xml?   -  person Paul Vargas    schedule 06.09.2014


Ответы (1)


Мне удалось решить эту проблему:

Итак, мой компонент источника данных был объявлен в контексте приложения. С другой стороны, моя внешняя фабрика компонентов была объявлена ​​в корневом контексте. Теперь bean-компоненты в корневом контексте не могут видеть bean-компоненты в контексте приложения. Итак, свойство beanfactory в моей External Bean Factory так и не было инициализировано. Мне потребовалось время, чтобы понять это, но, к счастью, это сработало!

person TimeToCodeTheRoad    schedule 06.09.2014