【问题标题】:Spring 5 @Cacheable is not working, Even though interceptor call is on the stackSpring 5 @Cacheable 不起作用,即使拦截器调用在堆栈上
【发布时间】:2019-11-05 05:03:15
【问题描述】:

我的 Cache 注释注册,正在 TRACE 日志中显示:

2019-11-04 23:55:52,229 TRACE AnnotationCacheOperationSource:102 - **Adding cacheable method 'getMaximumSimilarItems'** with attribute: [Builder[public java.lang.Integer com.quote.manager.impl.SystemConfigManagerImpl.getMaximumSimilarItems()] caches=[attachments] | key='#root.methodName' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless='' | sync='false']
@Cacheable(value = "attachments", key = "#root.methodName")
    public Integer getMaximumSimilarItems() {

        logger.info("GetMax");
        SystemConfig systemConfig = systemConfigDao.getSystemConfig();

        Integer maxSimilarItems = systemConfig.getMaximumSimilarItems();

        if(maxSimilarItems != null) {
            return maxSimilarItems;
        }

        return 20;
    }

还有调试时,

我在调用的堆栈上和调用之后看到缓存拦截器。但是,仍然没有缓存任何内容。我尝试了多种缓存实现。

关于在 Spring 的缓存实现中设置调试点的位置以找出它为什么不缓存的任何想法?

我尝试了 XML 配置和 Java 配置 @EnableCaching。

<bean id="cacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
        <property name="cacheManager">
        <bean class="org.springframework.cache.jcache.JCacheManagerFactoryBean" 
            p:cacheManagerUri="classpath:ehcache.xml" />
        </property>
    </bean> 

<cache:annotation-driven  cache-manager="cacheManager" />


2019-11-05 11:16:51,370  INFO Eh107CacheManager:378 - Registering Ehcache MBean javax.cache:type=CacheStatistics,CacheManager=file./home/work/workspace-quotes/.metadata/.plugins/org.eclipse.wst.server.core/tmp7/wtpwebapps/app/WEB-INF/classes/ehcache.xml,Cache=attachments
2019-11-05 11:16:51,756  INFO Eh107CacheManager:378 - Registering Ehcache MBean javax.cache:type=CacheStatistics,CacheManager=file./home/work/workspace-quotes/.metadata/.plugins/org.eclipse.wst.server.core/tmp7/wtpwebapps/app/WEB-INF/classes/ehcache.xml,Cache=attachments

我看到 ehCache.xml 中定义的缓存也在应用启动时注册,所以缓存正在启动。

<ehcache:config
  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  xmlns:ehcache='http://www.ehcache.org/v3'
  xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.1.xsd">

  <ehcache:cache alias="attachments">

    <ehcache:resources>
      <ehcache:heap unit="entries">100</ehcache:heap>
      <ehcache:offheap unit="MB">1</ehcache:offheap>
    </ehcache:resources>
  </ehcache:cache>
</ehcache:config>

【问题讨论】:

  • 你启用缓存了吗?将@EnableCaching 添加到主应用程序类。还有,这里的methodName是什么?
  • 我刚刚更新了问题,我粘贴了我的配置。 root.methodName 应该是方法的名称,但我也试过没有任何键,并且使用没有键的虚拟参数,它仍然不起作用。根据这个文档docs.spring.io/spring/docs/3.2.0.RC1/reference/html/cache.html #root.methodName 应该是被调用方法的名称。
  • 是否有一些无效的表达式我可以放入@Cacheable 以使其抛出错误,只是为了确保它正在被处理?
  • 你是从另一个类调用getMaximumSimilarItems 方法吗? link
  • @MartinBG 是的,我是从另一个班级打来的。我发现了问题。该方法在@Service 中以@PostConstruct 标记的方法调用。如果我等待一切初始化,然后调用调用该方法的相同代码,那么它正在工作。看起来所有@Autowires 都必须完成,然后@Cacheable 才可用?在 MVC/Tomcat 可用之前,我需要以某种方式调用一些初始化代码,并且该代码应该具有 @Cacheable 工作。任何想法如何做到这一点?

标签: java spring spring-cache


【解决方案1】:

所以问题是我在初始化上下文之前过早地调用了@Cacheable 函数。一旦我调用它,它就可以正常工作了。

我补充说:

 implements Runnable, ApplicationListener<ContextRefreshedEvent>  {

@Override
public void onApplicationEvent(ContextRefreshedEvent arg0) {

String name = arg0.getApplicationContext().getDisplayName();

if (name.contains("Root")) {
    // ANY CODE That requires @Cacheable is called HERE!.. 
    // Will not work if ran before this, such as inside @PostConstruct

    }
}

“Root”检查是一种只有在 Root 事件完成时才调用的 hack,否则它会被调用两次。我不知道如何区分这些事件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2020-06-23
    • 2018-02-02
    相关资源
    最近更新 更多