2016-10-10 10 views
0

私は春とサーブレットベースのアプリケーションで作業しています。 私の要件は、データベースからデータをロードしてehcacheに保存することです。jbossサーバーが起動されると呼び出されるリスナーを作成しました。しかし、問題は私のアプリケーションでは、データベースに接続してDBからデータをロードするために春の休止状態のクラスを使用しています。 要件データはデータベースから取得し、キャッシュオブジェクト(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この状況をDIDサーバーが起動します。提案が役に立ちます。

--EDITED--

サーバがstarted.Butあるとき私は、ログファイルのprint文で確認したとき、私は)loaddataのを(呼び出すメソッドに@PostConstructを使用して、以下の方法を試していることを述べているありませんでしたこのメソッドは、サーバーの起動時に呼び出されていません。

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

答えて

0

は、サーブレットのものを使用しないでください、ちょうどあなたが@PostConstructアノテーション付きメソッドを持つBeanでやりたいが、それは必ずしも作成された第一豆ではありません。 Spring自体が始まる前に何かをする必要がある場合は、メインメソッドでアプリケーションコンテキストを手動で作成する必要があります。あなたが春の開始前に起こりたいことは、そのアプリケーションのコンテキストが作成される前である必要があります。他のビーンズの前にいくつかのビーンズを作成したい場合は、他のビーンズすべてに依存する必要があります。

+0

私はPostConstructを使用してみましたが、私は、そのサーバーを起動したときメソッドが呼び出されていません。 PostConstructのアノテーションを付けてメソッドを作成するには、他の設定を行う必要がありますか? – javaUser

+0

いいえ、Beanが作成されていることを確認してください。この場合、System.out.printlnか何かをコンストラクタに入れてください。 – Snickers3192

+0

注釈付きのメソッドPostConstructでSystem.out.printステートメントでクラスを作成しましたが、サーバーの起動時に呼び出されていませんでした。 – 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> 
関連する問題