简体   繁体   中英

Ehcache-spring-annotations @Cacheable not catching method with String object as parameter

I am using ehcache-spring-annotations-1.2.0.jar . This is my cache.xml file

<?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>

This is my 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" />

This is my main code

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.

    }
}

I have taken reference from

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

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

EditFirst Implementing the solution given below by kabochkov I have tested it .But also i am unable to cache.

I could not figure out where i have done mistake.Any help please?

I finally solved the problem.What mistake i was doing was that according to documentation https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable It was written You can place the @Cacheable annotation on a method on an interface, or a public method on a class . So before my method was not public .So i changed it to public and it worked.

If you create object directly, spring can't handle @Cacheable annotation.

EcacheSpringtest test = new EcacheSpringtest();

Use dependency injection and it will work!

@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 shoul'd be marked as @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";
}

}

One thing I doubt here is that there is no reference at all to your ehcache.xml in your context.

I have used ehcache in production with following configuration in context.xml and it works perfectly.

Could you try after adding following to context (Note: You'll have to remove <ehcache:annotation-driven /> and also add spring-cache xmlns to context)

<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" />

Add
xmlns:cache="http://www.springframework.org/schema/cache"

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM