2014-09-04 4 views
0

Чтобы использовать источник данных в моем приложении log4j, я написал пользовательский appender. Приложение пытается получить источник данных в качестве весеннего боба. Тем не менее, приложение не может получить компонент. Я использую стек технологий: mybatis, tomcat и spring.log4j custom jdbc appender, datasource

Мои 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 

Код для пользовательской Appender выглядит следующим образом:

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

Завод класс Внешний 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.

+1

Можете ли вы исправить форматирование? Благодаря! – admdrew

+0

@anmdrew: можете ли вы помочь решить проблему? – TimeToCodeTheRoad

+1

@TimeToCodeTheRoad Какая версия Spring? Используете ли вы свой сервлет или его список в своем web.xml? –

ответ

0

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

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

Смежные вопросы