他のアプリケーションで使用するjarを生成するutilモジュールがあります。このモジュールでキャッシングを使用したいので、Springのannotation-driven
キャッシングを使用したいと思います。
したがって、Util-Module
は次のようになります。
DataManager.Java
...
@Cacheable(cacheName="getDataCache")
public DataObject getData(String key) { ... }
...
data-manager-ehcache.xml
...
<cache name="getDataCache" maxElementsInMemory="100" eternal="true" />
...
data-manager-spring-config.xml
...
<cache:annotation-driven cache-manager="data-manager-cacheManager" />
<!-- ???? --->
<bean id="data-manager-cacheManager"
class="org.springframework.cache.ehcache.EhcacheCacheManager"
p:cache-manager="data-manager-ehcache"/>
<bean id="data-manager-ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="data-manager-ehcache.xml"/>
...
また、上記のjarを依存関係として含めながら、デプロイ可能なユニットにSpringアノテーションを介したキャッシュを持たせたいと思います。したがって、私のDeployable-Unit
は次のようになります。
MyApp.Java
...
@Cacheable(cacheName="getMyAppObjectCache")
public MyAppObject getMyAppObject(String key) { ... }
...
my-app-ehcache.xml
...
<cache name="getMyAppObjectCache" maxElementsInMemory="100" eternal="true" />
...
my-app-spring-config.xml
...
<cache:annotation-driven cache-manager="my-app-cacheManager" />
<!-- ???? --->
<bean id="my-app-cacheManager"
class="org.springframework.cache.ehcache.EhcacheCacheManager"
p:cache-manager="my-app-ehcache"/>
<bean id="my-app-ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="my-app-ehcache.xml"/>
...
構成を分離したまま、メインプロジェクトと依存関係モジュールの両方でアノテーション駆動型キャッシュを使用することは可能ですか?
そうでない場合は、なぜそうではないのかを説明していただければ幸いです。その場合、上記の構成で何を変更する必要があるかについての説明をいただければ幸いです。
これは3.2M1で修正されているようです。 https://jira.springsource.org/browse/SPR-8696 を参照してください。
このクラスを使用: http://static.springsource.org/autorepo/docs/spring/3.2.0.M1/api/org/springframework/cache/support/CompositeCacheManager.html このように:
<cache:annotation-driven cache-manager="cacheManager" />
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<array>
<ref bean="cacheManager1" />
<ref bean="cacheManager2" />
</array>
</property>
<property name="addNoOpCache" value="true" />
</bean>
Springは現在、cacheManagerがシングルトンであることを期待しています。これはehcache-spring-annotationsプロジェクトが遭遇したものであり、リクエストが満たされるのをまだ見ていません。 http://code.google.com/p/ehcache-spring-annotations/issues/detail?id=76
すべてのものと同様にJavaおよびSpringには、クラスを再実装するオプションがあります。
http://forums.terracotta.org/forums/posts/list/5618.page#2796 は、一部の人々が回避策として思いついた基本的な説明を提供し、
彼らが思いついた実際のコードです。このアプローチは従うべき規則を作成しますが、説明されている実際のアプローチが気に入らない場合は、独自のバージョンでこれを再実装するのは簡単です。
私のプロジェクトでは、ABC jar内でXYZ warを使用しており、両方ともSpring 3.1、xml駆動型構成のehCache(ehCacheがあります)を実装しています。 xml、次にspring-context.xml。両方のプロジェクトでSpring AOPを介してキャッシュをインターセプトしています)。そして、次のエラーが発生します。
Java.lang.IllegalArgumentException: Cannot find cache named [xxxxxx] for CacheableOperation[] caches=[Cxxxxxxxx] | condition='' | key='#xxxxxxxxxxxxx'
at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.Java:163) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.Java:443) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.Java:173) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.createOperationContext(CacheAspectSupport.Java:404) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.Java:192) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.Java:66) [spring-context-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.Java:90) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.Java:172) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.Java:622) [spring-aop-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at com.infy.flypp.dao.ContentDAO$$EnhancerByCGLIB$$9443481.getContentById(<generated>) [cglib-2.2.2.jar:]
ソリューション:
これが私たちがこの問題を解決した方法です:
ABCehCache.xml
(ABC jarから)からXYZehCache.xml
(XYZ戦争から)にコピーしました。ABCehCache.xml
(ABC jarから)を削除しましたが、ehCache.xml
内のすべての構成(ABC-spring.xml
およびSpringAOPのBeanインスタンス化など)は同じままです。XYZ-spring.xml
で、ABC-spring.xml
をインポートし、複合キャッシュマネージャーを定義しました。サポートされている構成ファイル:
ABC-spring.xml:
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="CacheManager1" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"></property>
</bean>
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:ABCEhcache.xml" />
XYZ-spring.xml:
<import resource="classpath*:ABC-spring.xml" />
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<array>
<ref bean="CacheManager1" />
<ref bean="CacheManager2" />
</array>
</property>
<property name="fallbackToNoOpCache" value="true" />
</bean>
<bean id="CacheManager2" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cache-manager-ref="ehcache" />
<bean id="ehcache"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location="classpath:XYZEhcache.xml" />
次のはるかに簡単な代替案を検討します。
CompositeCacheManagerのソリューションは、その動作が基になるキャッシュの実装に大きく依存しているため、気に入らなかった。基になるすべてのキャッシュマネージャーが不明なキャッシュ名でnullを返した場合にのみ、期待どおりに機能する。一部の実装では、それらをオンザフライで作成するため、予期しない構成のキャッシュが生成されます。