我使用基于java注释的配置来初始化基于ehcache的缓存,使用Spring 3.1。
以下是示例代码...
@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();
}
}
有一个有效的ehcache.xml,其中声明了1个缓存。
这是我用Spring初始化ehcache的所有配置。应用程序中没有基于XML的初始化。
在运行时,我注意到cacheManager()已按预期初始化。成功执行后,代码无法通过错误输出完成初始化:
CachingInterceptor.afterPropertiesSet() - >
if (this.cacheManager == null) {
throw new IllegalStateException("'cacheManager' is required");
}
我做了一些调查。
当ProxyCachingConfiguration正在初始化CachingInterceptor时,似乎会出现问题。
ProxyCachingConfiguration派生自AbstractCachingConfiguration。
AbstractCachingConfiguration有一个名为:
的方法@PostConstruct
protected void reconcileCacheManager()
不会调用此方法。如果被调用,在EhcacheConfig.cacheManger()中实例化的cacheManager将被正确设置以供CacheInterceptor.afterPropertiesSet()使用。
我不明白在调用CacheInterceptor.afterPropertiesSet()之前未调用reconcileCacheManager()的原因。
我错过了什么吗?有人可以帮我解决我面临的问题吗?
谢谢。
答案 0 :(得分:3)
首先,您可以考虑将EhCacheManagerFactoryBean的初始化提取为自己的@Bean方法。
这样您就可以简单地实例化,配置和返回FactoryBean,而无需自己调用afterPropertiesSet()。这确保了对象是一个管理得当的Spring bean,并且它可以接收任何其他可能注册的回调(比如DisposableBean#destroy())。
假设新的@Bean方法名为“ecmfb”,您只需从cacheManager()方法中调用ecmfb()。getObject(),就可以保证FactoryBean方法(即afterPropertiesSet) ())已经满意。
其次,您可能想知道您的@Bean方法可以抛出您喜欢的任何异常。因此,例如,如果您没有按照我的建议选择提取FactoryBean,您仍然可以通过在cacheManager @Bean方法上声明'throws Exception'子句来简化这种情况。这样可以节省当前的try / catch噪音。
最后,为了解决为什么没有调用@PostConstruct方法,让我问你是如何引导Spring容器的。如果您正在使用AnnotationConfig(Web)ApplicationContext,则默认情况下应注册CommonAnnotationBeanPostProcessor。如果你正在使用或者也是如此。 CABPP负责检测和处理注释,如@ PostConstruct,@ PreDestroy等。请提供有关您的自举方法的更多信息,我们将从那里开始。