Spring Memcached注释不是缓存

时间:2015-08-19 06:18:36

标签: java spring caching memcached simple-spring-memcached

我正在尝试让Memcache在Spring工作。

我使用Docker和Kitematic设置了本地Memcached服务器:

enter image description here

我可以使用telnet访问Memcached服务器:getParticipant(conf_url, function(data) { data.forEach(function(obj){ uid.push(obj['uid']); console.log(uid) }) if(uid[indexOfYourChoice] == '0090000165'){ document.write("true"); }else{ document.write("false"); } }); 然后运行telnet 192.168.99.100 32780stats(如果缓存为空,则仅打印出stats items);

我的END

pom.xml

在我 <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>simple-spring-memcached</artifactId> <version>3.6.0</version> </dependency> <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>spring-cache</artifactId> <version>3.6.0</version> </dependency> <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>xmemcached-provider</artifactId> <version>3.6.0</version> </dependency> 我有以下内容:

applicationContext.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <context:property-placeholder location="classpath*:META-INF/spring/*.properties"/> ... <import resource="cacheContext.xml" /> ... 我的配置如下:

cacheContext.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:cache="http://www.springframework.org/schema/cache"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <aop:aspectj-autoproxy/>
    <cache:annotation-driven/>

    <context:component-scan base-package="com.google.code.ssm"/>
    <context:component-scan base-package="com.mycee.application"/>

    <bean id="cacheBase" class="com.google.code.ssm.aop.CacheBase"/>

    <bean id="readThroughSingleCache" class="com.google.code.ssm.aop.ReadThroughSingleCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="readThroughMultiCache" class="com.google.code.ssm.aop.ReadThroughMultiCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="readThroughAssignCache" class="com.google.code.ssm.aop.ReadThroughAssignCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="updateSingleCache" class="com.google.code.ssm.aop.UpdateSingleCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="updateMultiCache" class="com.google.code.ssm.aop.UpdateMultiCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="updateAssignCache" class="com.google.code.ssm.aop.UpdateAssignCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="invalidateSingleCache" class="com.google.code.ssm.aop.InvalidateSingleCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="invalidateMultiCache" class="com.google.code.ssm.aop.InvalidateMultiCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="invalidateAssignCache" class="com.google.code.ssm.aop.InvalidateAssignCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>

    <bean id="incrementCounterInCache" class="com.google.code.ssm.aop.counter.IncrementCounterInCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="decrementCounterInCache" class="com.google.code.ssm.aop.counter.DecrementCounterInCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="readCounterFromCache" class="com.google.code.ssm.aop.counter.ReadCounterFromCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>
    <bean id="updateCounterInCache" class="com.google.code.ssm.aop.counter.UpdateCounterInCacheAdvice">
        <property name="cacheBase" ref="cacheBase"/>
    </bean>

    <bean name="cacheManager" class="com.google.code.ssm.spring.SSMCacheManager">
        <property name="caches">
            <set>
                <bean class="com.google.code.ssm.spring.SSMCache">
                    <constructor-arg name="cache" index="0" ref="defaultCache"/>
                    <constructor-arg name="expiration" index="1" value="300"/>
                    <constructor-arg name="allowClear" index="2" value="false"/>
                </bean>
            </set>
        </property>
    </bean>

    <bean name="defaultCache" class="com.google.code.ssm.CacheFactory" depends-on="cacheBase">
        <property name="cacheName" value="defaultCache"/>
        <property name="cacheClientFactory">
            <bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/>
        </property>
        <property name="addressProvider">
            <bean class="com.google.code.ssm.config.DefaultAddressProvider">
                <property name="address" value="localhost:11211"/>
            </bean>
        </property>
        <property name="configuration">
            <bean class="com.google.code.ssm.providers.CacheConfiguration">
                <property name="consistentHashing" value="true"/>
            </bean>
        </property>
    </bean>


</beans>

要访问它我会:

@Component("cacheEndpoint")
public class CacheClass {

    @Autowired
    SSMCacheManager cache;

    public String getDateTime1(String anything) {

        SSMCache c = cache.getCache("defaultCache");

        String s = c.get(anything, String.class);
        if (s != null) {
            return s;
        }

        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        c.put(anything, response);

        return response;

    }

    @Cacheable("defaultCache")
    public String getDateTime2(String anything) {
        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        return response;
    }

    @ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
    public String getDateTime3(String anything) {
        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        return response;
    }


}

@Autowired CacheClass c; ... // caches perfectly c.getDateTime1("test"); // doesn't do any caching c.getDateTime2("test"); // doesn't do any caching c.getDateTime3("test"); getDateTime2中放置运行时异常后,确定没有调用拦截器。

知道getDateTime3@Cachable没有做出拦截魔法的原因是什么?

根据MatjažPečan的回复更新:

CacheClass接口:

@ReadThroughSingleCache

CacheClass实现:

public interface CacheClass {

    public String getDateTime1(String anything);

    public String getDateTime2(String anything);

    public String getDateTime3(String anything);

}

我正在测试缓存的SOAP端点:

@Component("cacheEndpoint")
public class CacheClassImpl implements CacheClass {

    @Autowired
    SSMCacheManager cache;

    public String getDateTime1(String anything) {

        SSMCache c = cache.getCache("defaultCache");

        String s = c.get(anything, String.class);
        if (s != null) {
            return s;
        }

        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        c.put(anything, response);

        return response;

    }

    @Cacheable("defaultCache")
    public String getDateTime2(String anything) {

        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        return response;

    }

    @ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
    public String getDateTime3(String anything) {

        Date d = new Date();
        String response = d.toString() + " - " + d.getTime();
        return response;

    }


}

cacheContext.xml:

@Endpoint
public class PingEndpoint {

    @Autowired
    CacheClass c;

    @ResponsePayload
    @PayloadRoot(localPart = "PingRequest", namespace = "http://www.mycee.com/Application")
    public PingResponse doPing(@RequestPayload PingRequest request) {

        // caches perfectly
        System.out.println(c.getDateTime1("test"));

        // doesn't do any caching
        System.out.println(c.getDateTime2("test"));

        // doesn't do any caching
        System.out.println(c.getDateTime3("test"));

    }
}

2 个答案:

答案 0 :(得分:2)

SSM 3.6.0中存在错误,请降级至3.5.0以解决问题或尝试添加

depends-on="cacheBase"

到defaultCache bean定义。

更新1

自我调用不起作用。如果通过对象进行调用,则不会拦截呼叫并且不会缓存结果。确保从另一个Spring bean调用bean中定义的方法。

更新2

对于SSM方法,必须注释如下:

@ReadThroughSingleCache(namespace = "defaultCache", expiration = 15000)
public String getDateTime3(@ParameterValueKeyProvider String anything) {
     ...
}

由于某些原因,仍然没有触发拦截器。

答案 1 :(得分:0)

Spring代理机制因使用的实现而不同。

默认值是AspectJ,它需要接口(逐个接口),然后这些接口将由包裹在bean中的实际代理实现。由于您的bean只是一个类而且没有接口,因此它不代表AspectJ。

有两种可能的解决方案:

  • 为CacheClass实现一个接口,并将该接口用于连接其他bean
  • 使用CGLib代理(您需要在CGLib上添加运行时依赖项)并在aspectj-proxy元素中添加proxy-target-class:

    <aop:aspectj-autoproxy proxy-target-class="true"/>