基于Java的Ehcache缓存配置不起作用

基于Java的Ehcache缓存配置不起作用,java,spring,configuration,ehcache,Java,Spring,Configuration,Ehcache,我使用基于java注释的配置来初始化基于ehcache的缓存,使用Spring3.1 下面是示例代码 @Configuration @EnableCaching public class EhcacheConfig implements CachingConfigurer { ..... @Bean public CacheManager cacheManager() { ..... EhCacheManagerFactoryBean

我使用基于java注释的配置来初始化基于ehcache的缓存,使用Spring3.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.AfterPropertieSet()->

我做了一些调查

当CachingInterceptor由ProxyCachingConfiguration初始化时,似乎出现了问题

ProxyCachingConfiguration源自AbstractCachingConfiguration

AbstractCachingConfiguration有一个名为:

@PostConstruct
protected void reconcileCacheManager()
不调用此方法。如果调用了它,则在EhcacheConfig.cacheManger()中实例化的cacheManager将被正确设置以供CacheInterceptor.AfterPropertieSet()使用

我不理解为什么在调用CacheInterceptor.AfterPropertieSet()之前不调用reconcileCacheManager()

我错过什么了吗?有人能帮我解决我面临的问题吗


谢谢。

首先,您可以考虑将EHCHACMeAgErraseBean bean初始化为其自己的“bean”方法。

这样,您就可以简单地实例化、配置和返回FactoryBean,而无需自己调用AfterPropertieSet()。这确保了该对象是一个被正确管理的Springbean,并且在这种特殊情况下,它可以接收可能注册的任何其他回调(如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和其他注释。请提供有关引导方法的更多信息,我们将从这里开始。

spring容器是使用ContextLoaderListener的AnnotationConfigWebApplicationContext上下文类初始化的。深入挖掘后,我发现jsr-250 jar必须位于/WEB-INF/lib中,@PostConstruct注释才能工作。我从()下载了它,效果很好。Chris,非常感谢您的帮助。@dhpd,aha-是的,如果您运行的是Java SE 1.5,JSR-250注释在默认情况下不可用,必须包含在其独立形式中。注意,对于Java1.6,情况正好相反-@PostConstruct和friends包含在标准发行版中,不再需要独立的jar。
@PostConstruct
protected void reconcileCacheManager()