2011-12-27 3 views
2

Spring 3.1과 함께 ehcache 기반 캐싱을 초기화하기 위해 자바 애노테이션 기반 구성을 사용하고 있습니다. 여기 Ehcache 기반 캐싱을위한 Java 기반 설정이 작동하지 않습니다.

은 선언 한 캐시 유효한 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 빈이고,이 특별한 경우에는 DisposableBean # destroy()와 같은 다른 콜백을 등록 할 수 있습니다.

새로운 @Bean 메소드의 이름이 "ecmfb"라고 가정하면 cacheManager() 메소드에서 ecmfb(). getObject()를 호출하면 FactoryBean 계약 (즉, afterPropertiesSet())이 만족되었습니다.

둘째, @Bean 메서드가 원하는 예외를 throw 할 수 있습니다. 예를 들어 위에서 제안한대로 FactoryBean 추출을 선택하지 않았다면 cacheManager @Bean 메소드에서 'throws Exception'절을 선언하여 상황을 단순화 할 수 있습니다. 이렇게하면 현재 try/catch 노이즈가 저장됩니다.

마지막으로 @PostConstruct 메소드가 호출되지 않는 이유를 설명하기 위해 Spring 컨테이너를 어떻게 부트 스트랩하는지 묻겠습니다.AnnotationConfig (Web) ApplicationContext로 작업하는 경우 CommonAnnotationBeanPostProcessor가 기본적으로 등록되어야합니다. 또는을 사용하는 경우에도 마찬가지입니다. CABPP는 @PostConstruct, @PreDestroy 및 기타와 같은 주석의 검색 및 처리를 담당합니다. 부트 스트래핑 접근법에 대해 좀 더 자세한 정보를 제공해주십시오.

+0

스프링 컨테이너는 ContextLoaderListener의 AnnotationConfigWebApplicationContext 컨텍스트 클래스를 사용하여 초기화됩니다. – dhpd

+0

더 깊게 파고 들자 jsr-250 jar가 @PostConstruct 주석이 작동하려면/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는 더 이상 필요하지 않습니다. –

관련 문제