복붙노트

[SPRING] 여러 모듈에서 Spring 캐시 주석 사용하기

SPRING

여러 모듈에서 Spring 캐시 주석 사용하기

다른 응용 프로그램에서 사용할 항아리를 생성하는 util 모듈이 있습니다. 이 모듈이 캐싱을 사용하고 Spring의 주석 기반 캐싱을 사용하기를 원합니다.

따라서 Util-Module은 다음과 같이됩니다 :

DataManager.java

...
@Cacheable(cacheName="getDataCache")
public DataObject getData(String key) { ... }
...

데이터 관리자 -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"/>
...

기본 프로젝트와 종속성 모듈 모두에서 주석 기반 캐싱을 사용하면서 구성을 분리 된 상태로 유지할 수 있습니까?

그렇지 않은 경우 이유에 대한 설명을 이해할 수 있습니다. 그렇다면, 위의 구성에서 변경해야 할 사항에 대한 설명을 이해할 수 있습니다.

해결법

  1. ==============================

    1.이것은 3.2M1에서 수정 된 것 같습니다. https://jira.springsource.org/browse/SPR-8696을 참조하십시오.

    이것은 3.2M1에서 수정 된 것 같습니다. https://jira.springsource.org/browse/SPR-8696을 참조하십시오.

  2. ==============================

    2.이 클래스 사용 : http://static.springsource.org/autorepo/docs/spring/3.2.0.M1/api/org/springframework/cache/support/CompositeCacheManager.html 이렇게 :

    이 클래스 사용 : 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>
    
  3. ==============================

    3.Spring은 현재 cacheManager가 Singleton이 될 것으로 기대하고 있습니다. 이것은 ehcache-spring-annotations 프로젝트가 실행 된 것입니다. 아직 요청이 완료되었는지 확인하지 못했습니다. http://code.google.com/p/ehcache-spring-annotations/issues/detail?id=76

    Spring은 현재 cacheManager가 Singleton이 될 것으로 기대하고 있습니다. 이것은 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#27960은 일부 사람들이 해결 방법으로 생각해내는 것과 그에 대한 기본 설명을 제공합니다.

    그들이 작성한 실제 코드입니다. 접근 방식은 따라야 할 규칙을 만들지 만 설명 된 실제 접근 방식이 마음에 들지 않으면 자신의 버전으로 이것을 다시 구현하기가 쉽습니다.

  4. ==============================

    4.내 프로젝트에서는 XYZ 전쟁에서 ABC jar를 사용하고 있는데, ehCache를 Spring 3.1, XML 기반의 환경 설정 (ehCache.xml이 있고 spring-context.xml이 있는데 두 프로젝트에서 Spring AOP를 통해 캐시를 가로채는 곳) . 그리고 우리는 다음과 같은 오류가 발생하고 있습니다 :

    내 프로젝트에서는 XYZ 전쟁에서 ABC jar를 사용하고 있는데, ehCache를 Spring 3.1, XML 기반의 환경 설정 (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:] 
    

    해결책:

    이것이 우리가이 문제를 해결 한 방법입니다.

    지원되는 구성 파일 :

    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" />
    
  5. ==============================

    5.훨씬 간단한 대안을 생각해 보겠습니다.

    훨씬 간단한 대안을 생각해 보겠습니다.

    CompositeCacheManager의 솔루션은 기본 캐시의 구현에 매우 의존하기 때문에 저는 그랬습니다. 모든 기본 캐시 관리자가 알 수없는 캐시 이름에 대해 null을 반환하면 예상대로 작동 할 것입니다. 일부 구현은 즉시 작성하여 예상치 못한 구성의 캐시를 생성합니다.

  6. from https://stackoverflow.com/questions/8658789/using-spring-cache-annotation-in-multiple-modules by cc-by-sa and MIT license