Ehcache-spring-annotations @Cacheable не улавливает метод с объектом String в качестве параметра

Я использую 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, я протестировал его. Но также я не могу кэшировать.

Я не мог понять, где я сделал ошибку. Любая помощь, пожалуйста?


person abishkar bhattarai    schedule 16.05.2013    source источник


Ответы (3)


Если вы создаете объект напрямую, 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";
}

}
person kabochkov    schedule 16.05.2013
comment
Не могли бы вы немного доработать этот код. Я не проводил такого тестирования. Спасибо. - person abishkar bhattarai; 16.05.2013
comment
Кабочков прав: вы должны создать свои beans с помощью Spring, если хотите использовать Spring. Кэширование SO будет работать только с экземпляром Spring. Использование новых не будет. Проверьте образцы Spring более внимательно и прочтите документацию Spring, чтобы изучить основы Spring, прежде чем пытаться использовать функцию кэширования. - person Jean-Philippe Briend; 16.05.2013
comment
Я последовал предложению Кабочкова. На этот раз я протестировал с помощью junit-теста с @Autowired EcacheSpringtest, но я также не могу кешировать. - person abishkar bhattarai; 16.05.2013
comment
Извините, я только что заметил, что вы используете стороннюю библиотеку кеширования Spring. Попробуйте родной весенний соус. См. javacodegeeks.com/2011/02/ - person kabochkov; 16.05.2013

Я наконец решил проблему. Какую ошибку я делал, это то, что согласно документации https://code.google.com/p/ehcache-spring-annotations/wiki/UsingCacheable Было написано: Вы можете разместить аннотацию @Cacheable в методе интерфейса или общедоступном методе в классе . Раньше мой метод не был публичным, поэтому я изменил его на публичный, и он сработал.

person abishkar bhattarai    schedule 17.05.2013
comment
Нет второй версии в качестве решения, предоставленного вами. Спасибо за это. - person abishkar bhattarai; 17.05.2013

В одном я сомневаюсь, что в вашем контексте вообще нет ссылки на ваш ehcache.xml.

Я использовал ehcache в производстве со следующей конфигурацией в context.xml, и он отлично работает.

Не могли бы вы попробовать после добавления следующего в контекст (Примечание: вам нужно будет удалить <ehcache:annotation-driven />, а также добавить xmlns Spring-cache в контекст)

<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

person Anuj Patel    schedule 16.05.2013
comment
я добавил этот код в свой xml-файл xmlns: cache = springframework.org/schema/cache xsi : springframework.org/schema/cache springframework.org/schema/cache/spring-cache.xsd, и он показывает мне ошибку cvc-complex-type.2.4. c: Соответствующий подстановочный знак является строгим, но для элемента «ehcache: annotation-driven» не найдено декларации. Можете ли вы помочь мне, как я могу решить эту проблему, посетите stackoverflow.com/questions/37826832/ - person Anuj Dhiman; 15.06.2016