在我的项目(Java Spring 3.2)中,我有一个用 @Cacheable 注释装饰的方法,我正在使用ehcache .

缓存工作正常,除非装饰代码抛出异常

@Override
@Cacheable(value = "fooById", key = "'idFoo ' + #idFoo"  , unless="#result == null")
public Foo getFooById(Integer idFoo, boolean valueA,
        boolean valueB) { 

    try{
          //private method that call a web service
           Foo theFoo = getFoo(fooById); 
            return foo;
     }
    catch(Exception e){ 
          return null;
    }
}

正如我在这里读到的那样https://stackoverflow.com/a/15775379/4341748我期待装饰方法在下一次使用相同idFoo的调用时执行 . 我无法弄清楚为什么这不会发生 .

我注意到的另一个问题是第二次调用没有从缓存中返回任何内容,并且 LOG.debug 未被执行

private void method(Integer id){
    Foo myFoo = fooService.getFooById(id, false, false);

    LOG.debug("foo received from cache or web services:" + foo.getName());
}

当Web服务返回正确的值时,缓存再次过期 . 相反,缓存仍然被阻止,并且在Web服务失败时不会过期!

这是我的配置

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
  <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="ehcache.xsd"
     name="mySharedCache"
     updateCheck="false" monitoring="autodetect"
     maxBytesLocalHeap="100M"
     dynamicConfig="false">
<diskStore path="javax.servlet.context.tempdir"/>
<defaultCache eternal="false"
              timeToIdleSeconds="120"
              timeToLiveSeconds="120"
              overflowToDisk="false"
              diskPersistent="false"
              diskExpiryThreadIntervalSeconds="120">
</defaultCache> 
<cache
    name="getFooById"
    eternal="false"
    overflowToDisk="false"
    diskPersistent="false"
    timeToLiveSeconds="120">
 <cacheDecoratorFactory class="it.solinfo.leonardo.sintesi.utils.BlockingCacheDecoratorFactory" />
</cache>

applicationContext.xml

<beans>
       <cache:annotation-driven />
       <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>
       <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true"/>
    </beans>