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

标签 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() 的原因。

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

谢谢。

最佳答案

首先,您可能会考虑将 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/

相关文章:

java - 第一个 REST Spring 应用程序

java - 如何在Android应用程序中使用Eclipse调试器?

java - 如何获取 modelMap 对象中的所有键值对,在 spring Controller 本身内部,由 java spring 框架中的 modelAndView.getModel() 返回

java - 在动态创建的类中实例化 spring bean

java - 在 Spring 4 中用带注释的 Controller 替换 BaseCommandController 和 SimpleFormController

java - Hibernate:根据实体类自动创建/更新数据库表

java - Ubuntu 上带 PCSC lite 的 SCL01x 非接触式读卡器

configuration - 如何恢复到 OpenWrt 路由器配置?

json - Heroku - 在 app.json 中配置调度程序

java - jar 外部的 ResourceBundle 文件