【问题标题】:Why doesn't my @Cachable annotated method cache the result with EHCache?为什么我的@Cachable 注释方法不使用 EHCache 缓存结果?
【发布时间】:2011-11-16 17:50:58
【问题描述】:

我在 Spring 中有一个拦截器,它自动连接两个不同的服务。 这两个服务都有来自 ehcache-spring-annotations 项目的带有 @Cacheable 标记的方法,但带有不同的 cacheNames

public class MenuInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private EventService eventService;

    @Autowired
    private OrganisationInfoService orgService;

    @Override
    public final void postHandle(HttpServletRequest request,
                       HttpServletResponse response,
                       Object handler,
                       ModelAndView modelAndView) throws SystemException {
        eventService.getFolderEventsForUser(123);
        orgService.getOrgCustomProfile("abc");

    }

@Service
public class EventServiceImpl implements EventService {
    @Override
    @Cacheable(cacheName = "ecomOrders")
    public Collection<FolderEventBean> getFolderEventsForUser(long loginId) throws SystemException {


@Service("organisationInfoService")
public class OrganisationInfoServiceImpl implements OrganisationInfoService {
    @Override
    @Cacheable(cacheName="orgProfile")
    public OrgCustomProfileBean getOrgCustomProfile(String orgHierarchyString) throws ServiceException {

当我运行我的应用程序时,一种方法成功地使用 EHCache 作为结果,而另一种方法则没有。 OrganisationInfoSericeImpl.getOrgCustomProfile() 缓存正确,而EventServiceImpl.getFolderEvnetsForUser 没有。谁能告诉我为什么?

我尝试为这两种服务使用相同的缓存,但仍然只有其中一种有效。 我为ehcache-spring-annotations打开了DEBUG,它在启动时注册了这两种方法:

[DEBUG] 08:09:01 () 添加带有属性的 CACHE 建议方法“getFolderEventsForUser”:CacheableAttributeImpl [cache=[ name = ecomOrders status = STATUS_ALIVE forever = false overflowToDisk = false maxElementsInMemory = 100 maxElementsOnDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 300 timeToIdleSeconds = 0 diskPersistent = false diskExpiryThreadIntervalSeconds = 120 cacheEventListeners:net.sf.ehcache.statistics.LiveCacheStatisticsWrapper hitCount = 0 memoryStoreHitCount = 0 diskStoreHitCount = 0 missCountNotFound = 0 missCountExpired = 0],cacheKeyGenerator=HashCodeCacheKeyGenerator [includeMethod=true,includeParameterTypes=true , useReflection=false, checkforCycles=false], entryFactory=null, exceptionCache=null, parameterMask=ParameterMask [mask=[]]] [] at com.googlecode.ehcache.annotations.impl.CacheAttributeSourceImpl.getMethodAttribute(CacheAttributeSourceImpl.java:174 )

[DEBUG] 08:09:01 () 添加带有属性的 CACHE 建议方法“getOrgCustomProfile”:CacheableAttributeImpl [cache=[ name = orgProfile status = STATUS_ALIVE ever = false overflowToDisk = false maxElementsInMemory = 200 maxElementsOnDisk = 0 memoryStoreEvictionPolicy = LRU timeToLiveSeconds = 86400 timeToIdleSeconds = 0 diskPersistent = false diskExpiryThreadIntervalSeconds = 120 cacheEventListeners:net.sf.ehcache.statistics.LiveCacheStatisticsWrapper hitCount = 0 memoryStoreHitCount = 0 diskStoreHitCount = 0 missCountNotFound = 0 missCountExpired = 0],cacheKeyGenerator=HashCodeCacheKeyGenerator [includeMethod=true, includeParameterTypes=true , useReflection=false, checkforCycles=false], entryFactory=null, exceptionCache=null, parameterMask=ParameterMask [mask=[]]] [] at com.googlecode.ehcache.annotations.impl.CacheAttributeSourceImpl.getMethodAttribute(CacheAttributeSourceImpl.java:174 )

拦截器调用自动装配服务时,只有其中一个缓存:

[DEBUG] 08:09:19 (UNIQUE_ID) 为调用生成密钥“-1668638847278617”:ReflectiveMethodInvocation: public abstract no.finntech.base.modules.organisation.support.OrgCustomProfileBean no.finntech.service.organisation.OrganisationInfoService。 getOrgCustomProfile(java.lang.String) 抛出 no.finntech.service.ServiceException;目标是类 [no.finntech.service.organisation.impl.OrganisationInfoServiceImpl] [URI:/finn/minfinn/myitems/list,远程 IP:127.0.0.1,Referer:,用户代理:Mozilla/5.0(Windows NT 6.1 ; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2] 在 com.googlecode.ehcache.annotations.interceptor.EhCacheInterceptor.generateCacheKey(EhCacheInterceptor.java:272)

编辑: 我应该提一下,这两个服务是在不同的 Maven 模块中定义的。

【问题讨论】:

    标签: java caching ehcache spring-annotations


    【解决方案1】:

    原来原因与上下文有关:组件扫描。 缓存失败的服务包含在两个不同的组件扫描中。一旦我确定缓存按预期工作。

    【讨论】:

      【解决方案2】:

      你怎么调用第二种方法,是通过OrganisationInfoService接口吗?注释依赖于通过接口调用方法,因此可以生成一个代理来进行缓存。

      如果您直接从外部调用具体类,或者从类中的另一个方法调用,则注释将不起作用。

      请参阅常见问题解答中的答案 3 和 4: http://code.google.com/p/ehcache-spring-annotations/wiki/FrequentlyAskedQuestions

      【讨论】:

      • 两者都是通过各自的接口调用的。
      • 嗯,与另一个缓存相比,第一个缓存的 timeToLive 值为 300 秒(即 86400 秒) - 这意味着缓存对象将在 5 分钟后被驱逐,无论上次访问时间如何,所以如果方法是只为给定的 loginId 很少调用它看起来像没有缓存的东西。可能是这个原因吗?
      • 目前我只是在测试它,并检查它是否被缓存。这些呼叫是在几秒钟内相互进行的。缓存代理从不用于 EventService,所以我猜肯定存在某种设置/配置问题。
      猜你喜欢
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-21
      • 2015-06-14
      • 1970-01-01
      • 2014-03-09
      • 1970-01-01
      相关资源
      最近更新 更多