首页 文章

@Cachable注释不起作用

提问于
浏览
3

我们在项目中使用ehcache进行缓存 .

import com.googlecode.ehcache.annotations.Cacheable;
// Other imports

@Component
public class Authenticator{
    @Cacheable(cacheName = "rest_client_authorized")
    public boolean isUserAuthorized(final String user, final String sessionId) {
        // Method code
    }
}

进入方法时,没有缓存拦截器 . 到目前为止我们检查的东西:

  • 我们不是从类内部调用此方法,而是从外部调用 . 所以问题不是导致绕过代理的内部调用 .

  • 我们为这个类添加了一个接口,我们更改了调用此类的注入,以使用接口表示而不是具体类 .

我们以这种方式在应用程序上下文中定义了缓存管理器:

<ehcache:annotation-driven cache-manager="ehCacheManager" />         
   <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
       <!-- use a share singleton CacheManager -->
       <property name="shared" value="true" />
   </bean>

缓存定义如下:

<cache name="rest_client_authorized"
            eternal="false"
            maxElementsInMemory="50"
            overflowToDisk="false" diskPersistent="false"
            timeToIdleSeconds="0" timeToLiveSeconds="600"
            memoryStoreEvictionPolicy="LRU" />

当我们使用Jconsole测试缓存管理器时,我们可以看到缓存* rest_auth_disabled *存在且为空 .

关于为什么这不起作用的任何想法将非常感激 . 谢谢!

Updates (aggregation from comments below)

========================================== **

这是一个遗留代码,可以很好地处理我提供的类和定义 . 我在这里讨论的方法是新的,但课程的其余部分确实在过去工作 . 因此,我们正在努力了解发生了哪些变化 . 我们还尝试将注释替换为spring Cacheable,但仍然没有:/可能这取决于调用此新方法的代码,该方法来自与我们用于其他方法的Spring bean不同的Spring bean . 但我仍然找不到问题 .

还尝试在下面的答案后返回布尔值而不是布尔值,但它不起作用 . 我们有一个新的领导,这可能与我们注入bean的方式有关(使用@Autowire) . 如果确实如此,将会更新 .

4 回答

  • 1

    此问题可能与Spring加载bean的顺序有关 . 尝试从Authenticator声明中删除@Autowire注释,并手动执行自动装配 . 就像是:

    /**
     * Class that uses Authenticator
     */
    
     public class X {
    
        // Don't use @autowire here
        public Authenticator athenticator;
    
        public void doSomething() {
             manuallyAutowire();
        }
    
        public void manuallyAutowire() {
             if(authenticator == null) {
        authenticator = ApplicationContextUtils.getApplicationContext().
                                getBean(authenticator.class);
        }
    }
    

    哪里

    @Component
    public class ApplicationContextUtils implements ApplicationContextAware {
    
        private static ApplicationContext ctx;
    
        @Override
        public void setApplicationContext(final ApplicationContext appContext) 
                                              throws BeansException {
             ctx = appContext;
    
        }
    
        public static ApplicationContext getApplicationContext() {
            return ctx;
        }
    }
    
  • 1

    @Cacheable中参数 cacheName 的值应与应用程序上下文中 <cache> 声明的 name 属性的值相同

  • 3

    我认为你在这里搞混合了 - 你使用了 com.googlecode.ehcache.annotations.Cacheable ,如果你想要 spring 缓存支持它应该实际上是 org.springframework.cache.annotation.Cacheable . 那么缓存拦截器应该干净利落 .

  • 1

    据我所知,Spring Ehcache注释建议将两个参数作为返回对象应该具有原始类型缺少的 equals()hashCode() 方法 .

    我不确定这个框架是否正在将原语转换为它们的包装变体(例如 IntegerBoolean ) . 尝试返回包装变体 Boolean 而不是原始类型,看它是否有效 .

    我不确定的另一件事是它如何(以及如果)处理 final 参数 . 如果我的第一个想法不起作用,请尽可能删除 final 关键字,看看它是否有效 .

相关问题