Ehcache-spring-annotations @Cacheable没有捕获String对象作为参数的方法

时间:2013-05-16 08:28:54

标签: java spring ehcache

我正在使用 ehcache-spring-annotations-1.2.0.jar。 这是我的cache.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:oxm="http://www.springframework.org/schema/oxm"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">

    <ehcache:annotation-driven />



    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>



</beans>

这是我的ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

        <cache name="messageCache" eternal="false"
        maxElementsInMemory="5" overflowToDisk="false" diskPersistent="false"
        timeToIdleSeconds="1000" timeToLiveSeconds="3000"
        memoryStoreEvictionPolicy="LRU" />

这是我的主要代码

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.googlecode.ehcache.annotations.Cacheable;

public class EcacheSpringtest {
    private static ApplicationContext cachecontext = new ClassPathXmlApplicationContext("cache.xml");

    @Cacheable(cacheName = "messageCache")
    String getName(String name) {

        System.out.println(name+ " "+"has not been found in the cache so called getName()");
        return "testObject";

    }

    public static void main(String[] args) {
        long starttime;
        long endtime;
        long calldifferencesecs;

        EcacheSpringtest test = new EcacheSpringtest();
        test.getName("test");
        try {
            starttime = System.currentTimeMillis();
            Thread.sleep(150);
            endtime = System.currentTimeMillis();
            calldifferencesecs = starttime - endtime ;
            System.out.println("preparing to call getName with test as paramter after" +" "+ (~calldifferencesecs)+1 +"milliseconds");
        } catch (InterruptedException e) {

        }
        test.getName("test"); // In this case testObject should be returned from cache  but it is again calling getName().The method getName() is again called when same "test" String object is passed to method after 1491 milliseconds.

    }
}

我参考了

http://ehcache.org/documentation/recipes/spring-annotations

https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable

EditFirst 实施kabochkov下面给出的解决方案我已经测试过了。但我也无法缓存。

我无法弄清楚我在哪里犯了错误。请帮忙吗?

3 个答案:

答案 0 :(得分:7)

我终于解决了这个问题。根据文档,我在做什么错误 https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable 它是写的 您可以将@Cacheable注释放在接口上的方法或类上的公共方法上。所以在我的方法没有公开之前。所以我把它改为公开并且有效。

答案 1 :(得分:5)

如果直接创建对象,则spring无法处理@Cacheable注释。

EcacheSpringtest test = new EcacheSpringtest();

使用依赖注入,它会起作用!

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:cache.xml"})
public abstract class TestEcacheSpring {

  @Autowired
  EcacheSpringtest test;

  @Test
  public void test(){
    test.getName("test");
    test.getName("test"); 
  }

}

EcacheSpringtest应标记为@Service

@Service
public class EcacheSpringtest {

@Cacheable(cacheName = "messageCache")
String getName(String name) {
 System.out.println(name+ " "+"has not been found in the cache so called getName()");
 return "testObject";
}

}

答案 2 :(得分:1)

我怀疑的一点是,在您的上下文中根本没有对您的ehcache.xml的引用。

我在生产中使用了ehcache,并在context.xml中使用了以下配置,它运行良好。

您可以在向上下文添加以下内容后尝试(注意:您必须删除<ehcache:annotation-driven />并将spring-cache xmlns添加到上下文中)

<cache:annotation-driven cache-manager="cacheManager" mode="proxy" proxy-target-class="true" />
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="classpath:ehcache.xml" p:shared="true" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache" />

添加
xmlns:cache =“http://www.springframework.org/schema/cache”

xsi:http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd