基于Java的配置基于Ehcache的缓存无法正常工作

时间:2011-12-27 15:58:23

标签: java spring configuration ehcache

我使用基于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()的原因。

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

谢谢。

1 个答案:

答案 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等。请提供有关您的自举方法的更多信息,我们将从那里开始。