2011-12-27 9 views
2

私は、Spring 3.1でehcacheベースのキャッシュを初期化するためのjava注釈ベースの設定を使用しています。ここでEhcacheベースのキャッシュのJavaベースの設定が動作しない

はそれで宣言された1つのキャッシュと有効ehcache.xmlがあり

@Configuration 
@EnableCaching 
public class EhcacheConfig implements CachingConfigurer { 

    ..... 

    @Bean 
    public CacheManager cacheManager() { 
     ..... 
     EhCacheManagerFactoryBean bean = new EhCacheManagerFactoryBean(); 
     bean.setCacheManagerName(CACHE_MANAGER); 
     bean.setShared(Boolean.TRUE); 
     File file = new File(property + Constants.Slash + EHCACHE_XML); 
     bean.setConfigLocation(new FileSystemResource(file)); 

     try { 
      bean.afterPropertiesSet(); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
     EhCacheCacheManager cm = new EhCacheCacheManager(); 
     cm.setCacheManager(bean.getObject()); 
     return cm; 
    } 

    public KeyGenerator keyGenerator() { 
     return new DefaultKeyGenerator(); 
    } 
} 

...サンプルコードです。

これは、Springでehcacheを初期化するために必要なすべての設定です。アプリケーションにXMLベースの初期化はありません。

実行時に、期待通りにcacheManager()が初期化されていることがわかりました。その実行が成功した後、コードは中出し誤ることにより、初期化を完了するために失敗します。

CachingInterceptor.afterPropertiesSet() - >

if (this.cacheManager == null) { 
    throw new IllegalStateException("'cacheManager' is required"); 
} 

私はいくつかの調査を行っています。

CachingInterceptorがProxyCachingConfigurationによって初期化されているときに問題が発生しているようです。

ProxyCachingConfigurationはAbstractCachingConfigurationから派生しています。このメソッドが呼び出されていない

@PostConstruct 
protected void reconcileCacheManager() 

AbstractCachingConfigurationと呼ばれる方法があります。それが呼び出されていれば、EhcacheConfig.cacheManger()でインスタンス化されたcacheManagerは、CacheInterceptor.afterPropertiesSet()によって使用されるように正しくセットアップされていました。

CacheInterceptor.afterPropertiesSet()が呼び出される前にreconcileCacheManager()が呼び出されない理由はわかりません。

何か不足していますか?私が直面している問題を助けてくれる人がいますか?

ありがとうございます。

答えて

3

まず、EhCacheManagerFactoryBeanの初期化を独自の@Beanメソッドに抽出することを検討します。

このようにして、afterPropertiesSet()を自分で呼び出すことなく、FactoryBeanのインスタンス化、設定、および返すことができます。これにより、オブジェクトが適切に管理されたSpring Beanであり、この特定のケースでDisposableBean#destroy()のように登録された他のコールバックを受け取ることができます。

新しい@Beanメソッドの名前が "ecmfb"であるとすると、ecmfb()。getObject()メソッドをcacheManager()メソッドから呼び出すだけで、その時点でFactoryBeanのコントラクトが保証されます。 afterPropertiesSet())が満たされています。

第2に、@Beanメソッドが好きな例外をスローすることがあることに気をつけるかもしれません。たとえば、上記のようにFactoryBeanを抽出することを選択しなかった場合、cacheManager @Beanメソッドに '例外をスローする'句を宣言することで、状況を単純化できます。これにより、現在のtry/catchノイズが節約されます。

最後に、なぜ@PostConstructメソッドが呼び出されていないのかを説明するために、Springコンテナをどのようにブートストラップしているのかを聞かせてください。AnnotationConfig(Web)ApplicationContextを使用している場合は、CommonAnnotationBeanPostProcessorをデフォルトで登録する必要があります。またはを使用している場合も同じです。 CABPPは@PostConstruct、@ PreDestroyなどのアノテーションの検出と処理を担当しています。あなたのブートストラップ方法についてもう少し情報を提供してください。私たちはそこから行くでしょう。

+0

Springコンテナは、ContextLoaderListenerのAnnotationConfigWebApplicationContextコンテキストクラスを使用して初期化されます。 – dhpd

+0

深く掘り下げて、@ PostConstructアノテーションが機能するためには、jsr-250 jarが/ WEB-INF/libにある必要があることが分かりました。私は(http://mvnrepository.com/artifact/javax.annotation/jsr250-api)からダウンロードして正常に動作しました。 クリス、多くのお手伝いをいただきありがとうございます。 – dhpd

+0

@dhpd、aha - はい、Java SE 1.5に対して実行している場合、JSR-250注釈はデフォルトでは使用できず、スタンドアロン形式に含める必要があります。 Java 1.6では逆のことが言えます - @ PostConstructとフレンドは標準ディストリビューションに含まれており、スタンドアロンのjarファイルはもはや必要ありません。 –

関連する問題