Memcached是前台应用系统主要的分布式缓存工具。为了简化操作,引入了SSM(Simple-Spring-Memcached)工具。
SSM本身不提供任何缓存,是为了简化缓存操作而设计的。所以,在缓存的实现上使用了第三方的组件:spymemcached,xmemcached 和 aws-elasticache 。
SSM的源代码托管:https://github.com/ragnor/simple-spring-memcached
SSM的文档:https://code.google.com/p/simple-spring-memcached (非常遗憾,经常访问不了)
1、配置文件
1.1 依赖包
如果通过maven管理,引入非常简单。
<dependencies> <dependency> <groupId>com.google.code.simple-spring-memcached</groupId> <artifactId>xmemcached-provider</artifactId> <version>3.6.0</version> </dependency> </dependencies>
1.2 spring的配置文件
新增:
<!--把CacheBase注入到Advice中,默认使用自己jar包中的配置文件-->
<import resource="classpath:simplesm-context.xml"/>
<!--打开aop注解-->
<aop:aspectj-autoproxy/>
<!--定义缓存客户端-->
<bean name="defaultMemcachedClient" class="com.google.code.ssm.CacheFactory">
<property name="cacheClientFactory">
<!--可配置不同的客户端,比如sypMemcached等-->
<bean class="com.google.code.ssm.providers.xmemcached.MemcacheClientFactoryImpl"/>
</property>
<property name="addressProvider">
<!--缓存服务器集群地址,还可以使用JndiAddressProvider-->
<bean class="com.google.code.ssm.config.DefaultAddressProvider">
<!--缓存集群地址-->
<property name="address" value="${memcached.servers}"/>
</bean>
</property>
<property name="configuration">
<bean class="com.google.code.ssm.providers.CacheConfiguration">
<property name="consistentHashing" value="true"/>
<!--缓存操作超时时间-->
<property name="operationTimeout" value="${memcached.timeout}"/>
<!--3.3.0版本后,新增了keyName的前缀功能,可能是考虑到不同应用使用同一个集群,避免KEY覆盖的情况。useNameAsKeyPrefix keyPrefixSeparator-->
</bean>
</property>
</bean>
<!--加载properties文件->
<beans profile="zsc1">
<context:property-placeholder location="classpath:zsc1/*.properties,classpath:*.properties" file-encoding="utf-8" />
</beans>
<beans profile="zsc2">
<context:property-placeholder location="classpath:zsc2/*.properties,classpath:*.properties" file-encoding="utf-8" />
</beans>
<beans profile="pro">
<context:property-placeholder location="classpath:pro/*.properties,classpath:*.properties" file-encoding="utf-8" />
</beans>1.3 memcached.properties文件
#集群 主节点,备节点 主节点,备节点 #memcached.servers=172.16.20.1:11211,172.16.20.2:12211 172.16.20.3:11211,172.16.10.4:12211 172.16.10.5:11212,172.16.10.6:12211 172.16.10.7:11212,172.16.20.8:12211 memcached.servers=172.16.50.66:11211 memcached.timeout=1000
2、注解
SSM本质上是采用了AOP的方式来实现缓存的调用和管理,其核心组件声明了一些Advice,当遇到相应的切入点时,会执行这些Advice来对memcached加以管理。
切入点是通过注解的方式来进行声明的,在项目开发时,通常在方法上加以相应的注解描述,来表示组件对该方法的拦截。
组件所提供的切入点主要包括以下几种:
ReadThroughSingleCache、ReadThroughMultiCache、ReadThroughAssignCache
当遇到查询方法声明这些切入点时,组件首先会从缓存中读取数据,取到数据则跳过查询方法,直接返回。取不到数据在执行查询方法,并将查询结果放入缓存,以便下一次获取。
InvalidateSingleCache、InvalidateMultiCache、InvalidateAssignCache
当遇到删除方法声明这些切入点时,组件会删除缓存中的对应实体。
UpdateSingleCache、UpdateMultiCache、UpdateAssignCache
当遇到更新方法声明这些切入点是,组件会更新缓存中对应的实体,以便下次从缓存中读取出的数据状态是最新的。
缓存的keyName,一般是由namespace 和 唯一性的值组合而成。
CacheKeyMethod、ParameterValueKeyProvider 生成缓存key。
以下是这些注解的详细使用说明:
@CacheName:指定缓存实例注解
@CacheKeyMethod:缓存key生成注解
--------------------------------- 读取 ---------------------------------
2.1 ReadThroughSingleCache
读取单个缓存
从缓存中读取value,如果缓存中没有,执行被注解的方法体,并将执行结果放倒缓存中。返回方法体的执行结果。
keyName的生成,通过 获取注解中的 namespace属性值以及ParameterValueKeyProvider 和 CacheKeyMethod注解的内容 获取。
ReadThroughSingleCache源码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@CacheOperation({CacheOperation.Type.READ, CacheOperation.Type.SINGLE})
public @interface ReadThroughSingleCache {
/**
* A namespace that is added to the key as it is stored in the distributed cache. This allows differing object that
* may have the same ID to coexist. This value must be assigned.
*
* @return the namespace for the objects cached in the given method.
*/
String namespace() default AnnotationConstants.DEFAULT_STRING;
/**
* The exp value is passed along to memcached exactly as given, and will be processed per the memcached protocol
* specification:
*
* The actual value sent may either be Unix time (number of seconds since January 1, 1970, as a 32-bit value), or a
* number of seconds starting from current time. In the latter case, this number of seconds may not exceed
* 60*60*24*30 (number of seconds in 30 days); if the number sent by a client is larger than that, the server will
* consider it to be real Unix time value rather than an offset from current time.
*
* (Also note: a value of 0 means the given value should never expire. The value is still susceptible to purging by
* memcached for space and LRU (least recently used) considerations.)
*
* @return expiration of cached data
*/
int expiration() default 0;
}例子:
namespace:命名空间
expiration:缓存时间
/**
* 获取银行列表接口查询结果,该结果获取后会被缓存。
* KEY:CacheConstant.NAMESPACE_BANK_LIST_INFO 和 BankListIn 对象中getCacheKey() 方法的返回值的组合。
*/
@ReadThroughSingleCache(namespace = CacheConstant.NAMESPACE_BANK_LIST_INFO, expiration = CacheConstant.EXP_SECONDS_BANK_LIST_INFO)
public UniResult<List<BankListOut>> getBankList(@ParameterValueKeyProvider BankListIn bankListIn)
throws Throwable {
// 序列化接口入参
String url = InterfaceConfig.getInterface("/tianyimall/banklist");
url = URLUtil.ObjectToURL(url, bankListIn);
// 反序列化接口出参
return excuteGet(url, new TypeReference<UniResult<List<BankListOut>>>() {});
}BankListIn
public class BankListIn implements Serializable{
private static final long serialVersionUID = 9168068757534717931L;
/**
* 类型
*/
private String type;
/**
* 支付平台ID
*/
private String paymentplatformid;
/**
* type.
*
* @return the type
* @since
*/
public String getType() {
return type;
}
/**
* type.
*
* @param type the type to set
* @since
*/
public void setType(String type) {
this.type = type;
}
/**
* paymentplatformid.
*
* @return the paymentplatformid
* @since
*/
public String getPaymentplatformid() {
return paymentplatformid;
}
/**
* paymentplatformid.
*
* @param paymentplatformid the paymentplatformid to set
* @since
*/
public void setPaymentplatformid(String paymentplatformid) {
this.paymentplatformid = paymentplatformid;
}
@CacheKeyMethod
public String getCacheKey(){
return type+"_"+paymentplatformid;
}
}2.2 ReadThroughMultiCache
@ReadThroughMultiCache(option = @ReadThroughMultiCacheOption(generateKeysFromResult = true)):读取多个缓存
@ReadThroughMultiCacheOption(generateKeysFromResult = true) 读取多个缓存操作generateKeysFromResult 通过结果生成key
例子:ReadThroughMultiCache
@ReadThroughMultiCache(namespace = CacheConstant.NAMESPACE_BASIC_INFO, expiration = CacheConstant.EXP_SECONDS_BASIC_INFO)
public List<SPProductInfo> getProductBasicInfoByPids(@ParameterValueKeyProvider List<String> salesPids) throws Throwable {
List<SPProductInfo> list = new ArrayList<>();
for (String salesPid : salesPids) {
list.add(getProductBasicInfoByPid(salesPid));
}
return list;
}2.3 ReadThroughAssignCache
这个注解在没有参数,也就是没有@ParameterValueKeyProvider 的时候,会指定key,比如下面的SomePhatKey
@ReadThroughAssignCache(assignedKey = "SomePhatKey", namespace = "Echo", expiration = 3000): 读取指定key缓存
例子:ReadThroughtAssignCache
@ReadThroughAssignCache(assignedKey = "userKey", namespace = "test", expiration = 3000)
public List getAllUser(){
System.out.println("没有缓存命中");
List l = new ArrayList(3);
l.add("1");
return l;
}--------------------------------- 失效 ---------------------------------
InvalidateSingleCache
@InvalidateSingleCache(namespace = SINGLE_NS):失效单个缓存
InvalidateMultiCache
@InvalidateMultiCache(namespace = "Delta") : 失效多个缓存
InvalidateAssignCache
@InvalidateAssignCache(assignedKey = "SomePhatKey", namespace = "Echo") : 指定key失效缓存
InvalidateAssignCache
@InvalidateAssignCache(assignedKey = "userKey", namespace = "test")
// assignedKey 也是不可缺少的,参数和返回值 不是必须的
public User delete() throws Exception{
User user = new User();
return user;
}--------------------------------- 更新 ---------------------------------
UpdateSingleCache
@UpdateSingleCache(namespace = SINGLE_NS, expiration = 2): 更新单个缓存(namespace 命名空间, expiration 失效时间单位秒)
UpdateMultiCache
@UpdateMultiCache(namespace = "Bravo", expiration = 300): 更新多个缓存
UpdateAssignCache
@UpdateAssignCache(assignedKey = "SomePhatKey", namespace = "Echo", expiration = 3000): 指定key更新缓存
UpdateMultiCacheOption
--------------------------------- 参数 ---------------------------------
ParameterDataUpdateContent
@ParameterDataUpdateContent: 标记方法的参数作为更新内容。这个注解应结合Update*Cache注解使用
ParameterValueKeyProvider
@ParameterValueKeyProvider: 标记将方法的参数做为计算缓存key.如果方法被注解的对象标记CacheKeyMethod的方法将会用来生成缓存key否则调用toString()生成
@ParameterValueKeyProvider(order=0): 属性表示如果多个参数做为key时需提供参数顺序
与@ParameterValueKeyProvider类似的注解有:
{
@ReturnValueKeyProvider: 返回值对象中计算key
}
ReturnDataUpdateContent
spring xmemcached 注解介绍
http://greemranqq.iteye.com/blog/2169594
simple-spring-memcached那些事三
http://my.oschina.net/orgsky/blog/424727?fromerr=bme8sZfS
未经允许请勿转载:程序喵 » SSM 之 simple-spring-memcached 使用手册
程序喵