1、在pom中添加:
<!-- simple spring memcached -->
<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>
<dependency>
<groupId>com.google.code.simple-spring-memcached</groupId>
<artifactId>spring-cache</artifactId>
<version>3.6.0</version>
</dependency>
2、在Spring配置文件中添加:
<!-- 引入properties配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath*:application.properties</value>
</list>
</property>
</bean>
<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
<cache:annotation-driven />
<import resource="simplesm-context.xml" />
<!-- simplesm-context.xml封装在simple-spring-memcached-*.jar文件当中,主要用来加载组件核心的Advice,供程序调度使用。而由于simple-spring-memcached主要是基于AOP的代理,所以加入<aop:aspectj-autoproxy />让代理机制起到作用-->
<aop:aspectj-autoproxy />
<!-- 缓存管理 -->
<bean name="cacheManager" class="com.google.code.ssm.spring.ExtendedSSMCacheManager">
<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="10" />
<constructor-arg name="allowClear" index="2" value="false" />
</bean>
</set>
</property>
</bean>
<bean name="defaultCache" class="com.google.code.ssm.CacheFactory">
<property name="cacheName" value="default" />
<!-- xmemcached配置方法 -->
<property name="cacheClientFactory">
<bean name="cacheClientFactory" class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl" />
</property>
<!-- 定义了缓存节点的IP地址和端口号 -->
<property name="addressProvider">
<bean class="com.google.code.ssm.config.DefaultAddressProvider">
<property name="address" value="${memcache.default.url}" />
</bean>
</property>
<!-- 定义了缓存节点的查找方法 -->
<property name="configuration">
<bean class="com.google.code.ssm.providers.CacheConfiguration">
<property name="consistentHashing" value="true" />
<property name="useBinaryProtocol" value="true" />
</bean>
</property>
</bean>
application.properties文件:
#memcache默认缓存地址
memcache.default.url=10.18.101.16\:11811
simplesm-context.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"
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">
<context:component-scan base-package="com.google.code.ssm" />
<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>
</beans>
3、配置完成,使用注解读写缓存:
public class UserDaoImpl implements IUserDao {
@Override
@ReadThroughSingleCache(namespace ="user", expiration = 3600) //3600秒=1小时
public User getById(@ParameterValueKeyProvider String userId) {
System.out.println(userId);
return users.get(userId);
}
}
因为Memcached有独立的服务器端组件,是独立于应用系统的,从客户端(应用系统)保存对象到memcached是必须通过网络传输,而网络传入都是二进制数据,所以必须经过序列化,否则无法存储到Memcached服务器端的缓存中。这里的User必须是可序列化的,需实现Serializable接口。
4、key的生成规则
目前我们系统中有两个不同的Memcached服务器:
session memcached服务器:主要存储用户的session
app memcached服务器: 主要用于缓存应用数据
由于应用所有的缓存数据都放在app缓存上,为避免各应用的缓存数据出现冲突,必须规划好它们的命名空间。所幸Simple-Spring-Memcached支持namespace的概念,namespace在生成key时,将放在最前面。
Simple-Spring-Memcached提供的针对单个对象的注解接口提供了两种key生成方式。
1)、AssignCache类注解通过assignKey指定key。只要求必须保证key不与其它的冲突,且namesapce符合规则。
2)、SingleCache类注解通过ParameterValueKeyProvider注解指定生成key的方法。
@ParameterValueKeyProvider: 将方法的参数做为缓存key。
@CacheKeyMethod标注的对象有getCacheKey()方法,根据getCacheKey()方法生成缓存key。
多个方法参数都作为Key时,@ParameterValueKeyProvider必须指明其order值。
多个方法参数作为Key时,参数之间用 ‘/’ 号分隔。
总之,key由命名空间namespace加上@ParameterValueKeyProvider标注的参数值组成。如:
步骤3中的key是user:${userId} (namespace:参数1/参数2)。
如果userId等于12,则key等于:user:12