简单实现了一个透明化的Cache机制,使用这种方式,可以尽可能的避免在业务逻辑中出现如下硬编码的Cache操作代码:
public LikeCount getCount(String appId, String contentId) {
Object value = cache.get("CACHE");
if(value == null){
value = ...
cache.set("CACHE", value)
}
return value;
}
主要的思路为:
使用方式如下:
@Cache(key = @CacheKey(template = "CACHE/${p0}/${p1}"))
public LikeCount getCount(String appId, String contentId) {
//Do something ...
}
${p0} 表示取方法的第一个参数
Cache框架通过Spring配置的拦截器来实现缓存的快捷操作,目前有3中拦截器类型:
MemcachedInterceptor 使用memcached进行缓存,配置方式如下:
<bean id="memcachedClient" class="net.spy.memcached.spring.MemcachedClientFactoryBean">
<property name="servers" value="${cache.server}"/>
<property name="protocol" value="BINARY"/>
<property name="transcoder">
<bean class="net.spy.memcached.transcoders.SerializingTranscoder">
<property name="compressionThreshold" value="1024"/>
</bean>
</property>
<property name="opTimeout" value="1000"/>
<property name="timeoutExceptionThreshold" value="1998"/>
<property name="hashAlg" value="KETAMA_HASH"/>
<property name="locatorType" value="CONSISTENT"/>
<property name="failureMode" value="Redistribute"/>
<property name="useNagleAlgorithm" value="false"/>
</bean>
<bean id="memcachedInterceptor" class="com.skymobi.sns.cache.memcached.MemcachedInterceptor">
<constructor-arg ref="memcachedClient"/>
</bean>
RedisInterceptor 使用redis进行缓存,支持list类型的数据
<bean id="masterRedisClient" class="com.skymobi.sns.cache.redis.RedisClient">
<constructor-arg value="${redis.url}"/>
</bean>
<bean id="slaveRedisClient" class="com.skymobi.sns.cache.redis.RedisClient">
<constructor-arg value="${redis-slave.url}"/>
</bean>
<bean id="redisInterceptor" class="com.skymobi.sns.cache.redis.RedisInterceptor">
<constructor-arg ref="masterRedisClient"/>
<constructor-arg ref="slaveRedisClient"/>
</bean>
HybridInterceptor 混合类型的拦截器
<bean id="hybridInterceptor" class="com.skymobi.sns.cache.hybrid.HybridInterceptor">
<property name="defaultInterceptor" ref="redisInterceptor"/>
<property name="interceptors">
<map>
<entry key="default" value-ref="redisInterceptor"></entry>
<entry key="memcached" value-ref="memcachedInterceptor"></entry>
</map>
</property>
</bean>
如果配置使用这种类型的拦截器,则在注解中可以通过type字段来指定使用的拦截器,将在下面具体说明。
最后需要在spring中配置一个Proxy bean,如下:
<bean id="cacheProxy" class="com.skymobi.sns.cache.EasyCacheProxy">
<constructor-arg ref="hybridInterceptor"/>
</bean>
@CacheProxy
需要在要使用cache支持的class上加上@CacheProxy注解。参数如下:
String type() default ""; //当配置了HybridInterceptor类型的拦截器时,可在这里指定整个bean默认使用的拦截器类型
@SimpleCache
最简单的缓存注解,缓存的key是简单字符串。参数如下:
String key(); //简单字符串,缓存的key
String type() default ""; //当配置了HybridInterceptor类型的拦截器时,可在这里指定当前方法使用的拦截器类型,将覆盖@CacheProxy的定义
int expire();//缓存过期时间,秒为单位
String expireTime() default ""; //过期时间,详细信息参见[#exireTime格式]
boolean cacheNull() default false; //是否缓存返回值为null的结果
@CacheKey
用来格式化缓存的key。参数如下:
String template(); //spring el表达式格式的字符串,通过 ${p0} ${p1} 来获取方法的参数,0,1代表的是在方法参数中的位置,对于复杂类型的参数,可以通过 ${p0.name}的方式来获取其字段
@Deprecated
String[] els() default {}; //已过期,无需使用
boolean simple() default false; //
@Cache
最常用的使用方式,被注解的方法在被调用时,首先尝试从缓存中加载数据,如果缓存命中,则直接返回。缓存中没有,则会调用方法本身,并在调用成功后将结果写入缓存。参数如下:
CacheKey key(); //缓存的key,通过@CacheKey指定
String type() default ""; //同@SimpleCache
String expireTime() default ""; //同@SimpleCache
int expire() default 0; //同@SimpleCache
boolean cacheNull() default false; //同@SimpleCache
@WriteCache
将方法的结果或者参数写入缓存。参数如下:
CacheKey key(); //同@CacheKey
String type() default ""; //同@CacheKey
int expire() default 0; //同@CacheKey
String expireTime() default ""; //同@CacheKey
boolean cacheNull() default false; //同@CacheKey
boolean writeParameter() default false; //是否写入参数
int parameterIndex() default 0; //要写入缓存的参数的index
boolean writeReturn() default true; //是否将方法的结果写入缓存
@RemoveCache
在调用这个方法是移除指定key对应的缓存。参数如下:
CacheKey[] key(); //同@CacheKey ,这里的key可以是多个
String type() default ""; //同@CacheKey
boolean markAsNull() default false; //是否将改key对应的缓存数据标记为null数据
int expire() default 0; //同@CacheKey
String expireTime() default ""; //同@CacheKey
boolean invokeBefore() default false; //默认是在方法调用成功后才会移除缓存,这里设置为true,则在调用方法前先清除缓存
ListedCache
用来缓存列表类型的数据,仅在使用RedisInterceptor类型的拦截器时或使用混合类型拦截器,并指定type为RedisInterceptor类型拦截器时可用,参数如下:
CacheKey key(); //同@CacheKey
String type() default ""; //同@CacheKey
int offsetIndex() default 1; //分页参数
int limitIndex() default 2; //分页参数
比如查询 offset=10, limit=10的数据,将首先尝试从缓存中加载,如果缓存中仅有18条数据,则首先从缓存中加载 offset=10, limit=8的数据,然后将修改传递给方法调用的参数为 offset=18, limit =2 ,将剩余的数据补充上。
@WriteListCache
写入列表类型的缓存,仅在使用RedisInterceptor类型的拦截器时或使用混合类型拦截器,并指定type为RedisInterceptor类型拦截器时可用,参数如下:
CacheKey key(); //同@CacheKey
String type() default ""; //同@CacheKey
boolean writeParameter() default false; //同@WriteCache
int parameterIndex() default 0; //同@WriteCache
boolean writeReturn() default true; //同@WriteCache
int max() default 1000; //控制redis缓存中列表的最大大小
boolean append() default false; //false时放在列表的最前面,为true则追加到列表的最后面。
@RemoveCache还可以和其他的注解一起使用,但是必须写在最前面,如下:
@RemoveCache(key = @CacheKey(template = "ddd", simple = true))
@Cache(key = @CacheKey(template = "fff", simple = true))
public void testM1(){
}
默认的redis客户端使用的是 async-redis-client,项目地址: async-redis-client
expire现在支持用字符串表达式来指定,如下:
exireTime = "1h"
可以使用的方式有 1d ---> 1天
1h ---> 1小时
1mn ---> 1分钟
1s --> 1秒
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。