簡體   English   中英

Spring Memcached注釋未緩存

[英]Spring Memcached annotations not Caching

我正在嘗試讓Memcache在Spring中工作。

我已經使用Docker和Kitematic設置了本地Memcached服務器:

在此處輸入圖片說明

我可以使用telnet來訪問Memcached服務器: telnet 192.168.99.100 32780 ,然后運行statsstats 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");

將運行時異常放入getDateTime2getDateTime3之后, getDateTime2未調用攔截器。

知道@Cachable@ReadThroughSingleCache沒有執行攔截魔術的原因是什么?

根據MatjažPečan的回復進行更新:

CacheClass接口:

public interface CacheClass {

    public String getDateTime1(String anything);

    public String getDateTime2(String anything);

    public String getDateTime3(String anything);

}

CacheClass的實現:

@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;

    }


}

我正在測試緩存的SOAP端點:

@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"));

    }
}

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 proxy-target-class="true"/>
    <cache:annotation-driven/>

    ...

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) {
     ...
}

出於某些原因,攔截器仍未觸發。

彈簧代理機制取決於使用哪種實現。

默認是AspectJ,它需要接口(按接口代理),然后這些接口將由包裝在bean周圍的實際代理來實現。 由於您的bean只是一個類,並且沒有接口,因此不使用AspectJ進行代理。

有兩種可能的解決方案:

  • 為CacheClass實現一個接口,並在連接到其他bean時使用該接口
  • 使用CGLib代理(您將需要在CGLib上添加運行時依賴項),並在Aspectj-proxy元素中添加proxy-target-class:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM