我使用基于 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() 的原因。
我错过了什么吗?有人可以帮助我解决我面临的问题吗?
谢谢。
最佳答案
首先,您可能会考虑将 EhCacheManagerFactoryBean 的初始化提取到它自己的 @Bean 方法中。
这样您就可以简单地实例化、配置和返回 FactoryBean,而无需自己调用 afterPropertiesSet()。这确保了该对象是一个正确管理的 Spring bean,并且在这种特殊情况下它可以接收可能注册的任何其他回调(例如 DisposableBean#destroy())。
假设新的@Bean方法被命名为“ecmfb”,您可以简单地从cacheManager()方法中调用ecmfb().getObject(),此时您将保证FactoryBean契约(Contract)(即afterPropertiesSet) ())已满足。
其次,您可能想知道您的 @Bean 方法可以抛出您喜欢的任何异常。因此,例如,如果您没有按照我上面的建议选择提取 FactoryBean,您仍然可以通过在您的 cacheManager @Bean 方法上声明“抛出异常”子句来简化情况。这将为您节省当前的 try/catch 噪音。
最后,为了解决为什么 @PostConstruct 方法没有被调用,让我问一下你是如何引导 Spring 容器的。如果您使用 AnnotationConfig(Web)ApplicationContext,则应默认注册 CommonAnnotationBeanPostProcessor。如果您使用 or ,情况也是如此。 CABPP 负责检测和处理 @PostConstruct、@PreDestroy 等注释。请提供有关您的引导方法的更多信息,我们将从那里开始。
关于基于 Java 的基于 Ehcache 的缓存配置不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8646582/