2016-10-10 23 views
0

我正在研究基于spring和servlet的应用程序。 我的要求是从数据库加载数据并存储在ehcache中。我写了一个监听器,一旦jboss服务器启动就调用它。但问题出在我的应用程序中,我们使用spring hibernate类来连接数据库并从数据库加载数据。 根据要求,数据必须从数据库中检索并存储在缓存对象(ehcache)中。但是,当侦听器类被加载时,其他XML配置文件(applicationContext.xml ..)尚未加载到配置数据源详细信息以连接到数据库的位置。以下是我的代码:服务器启动时从数据库加载值

监听器类。

import net.sf.ehcache.*; 
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 
/imports 
public class MyInitializationListener extends HibernateDaoSupport implements ServletContextListener { 

    /** Singleton instance of CacheManager. */ 
    private static CacheManager singletonManager = null; 

    public void contextDestroyed(ServletContextEvent arg0) { 
     System.out.println("--ServletContextListener destroyed*--"); 
    } 
    private static CacheManager getInstance() { 
     if (singletonManager == null) { 
      singletonManager = CacheManager.create(); 
     } 
     return singletonManager; 
    } 

    private Cache getCache() { 
     Cache cache = null; 
     cache = MyInitializationListener.getInstance().getCache("myCache"); 
     return cache; 
    } 
    // Run this before web application is started 

    public void contextInitialized(ServletContextEvent arg0) { 
    final Cache cache = getCache(); 
     final String dbValue = getDBValue(); 
     //logic here 
     } 
public String getDBValue() throws DataLayerException{ 
    //logic to get the value from database 

} 

以下是例外:

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/eas-webservice/ivr]] Exception sending context initialized event to listener instance of class com.data.listener.MyInitializationListener 
java.lang.NullPointerException 

没有任何一个面对这种情况before.What将是最好的方式连接到数据库,并在得到缓存从数据库和存储的值服务器启动。建议会有帮助。

--EDITED--

我试着使用@PostConstruct的方法来调用loadData()当服务器started.But当我在日志文件中打印语句检查以下方式是不存在其中规定,该方法在服务器启动时未被调用。

@Component 
public class MyDataStore { 
    @PostConstruct 
    public void loadData() 
    { 
     System.out.println("--In @postconstruct, loadData-"); 
    } 
} 

回答

0

不要使用servlet的东西,只是你在带注释@PostConstruct的方法豆想要什么,但不一定会被创建的第一个豆。如果你在spring自己启动之前需要做任何事情,你需要手动在main方法中创建应用程序上下文。任何你想在春季开始之前发生的事情都需要在创建应用程序上下文之前进行。如果你想在别人之前创建一些bean,那么它将需要成为所有其他bean的依赖项,这真的很烦人,不知道有任何其他方式来做到这一点。

+0

我试着用PostConstruct,但是当我开始在服务器没有调用PostConstruct的方法。我是否需要进行其他配置以使PostConstruct的工作方式变为可用? – javaUser

+0

不能,但确保bean正在创建。将System.out.println或其他东西放在构造函数中以确保是这种情况。 – Snickers3192

+0

我已经使用带有System.out.print语句的注释方法PostConstruct创建了该类,并且在服务器启动时未调用该类。 – javaUser

0

您不清楚您的问题,您为什么需要在ServletContextListener中准确执行缓存逻辑,但我可以建议如何在其中访问您的applicationContext

您可以使用缓存逻辑扩展org.springframework.web.context.ContextLoaderListener并使用它来加载应用程序上下文。另外如果你需要HibernateDaoSupport逻辑,那么它可以使用组合而不是继承来添加。

所以这一切可能看起来像如下:

MyInitializationListener

public class MyInitializationListener extends ContextLoaderListener { 

    private static CacheManager singletonManager = null; 

    pirvate HibernateDaoSupport hibernateDaoSupport; 

    ...... 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     super.contextInitialized(event); 

     ApplicationContext applicationContext = getCurrentWebApplicationContext(); 

     hibernateDaoSupport = applicationContext.getBeansOfType(HibernateDaoSupport.class).values().iterator().next(); 

     //Do cahcing logic you need; 
    } 

    ...... 

} 

的web.xml

<!-- spring framework context configuration --> 
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>MyInitializationListener</listener-class> 
</listener> 
相关问题