2016-10-10 48 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> 
相關問題