在项目中,使用缓存的方式有很多种,一般我们会封装出一个工具类以供使用,但是这样对代码的侵入性还是太强,在这里给大家介绍一种,使用自定义注解自动缓存内容,降低缓存与逻辑代码的耦合性,也省去了大家封装的时间,注意:key生成策略为(标识字符+首个参数值)
一,代码实现:
1,自定义注解:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
String value();
String key() default "";
int expireSeconds() default 0;
}
2,aop代码:
public class CacheInterceptor implements MethodInterceptor {
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
public CacheInterceptor() {
}
private Object generateKey(String key, MethodInvocation invocation) {
return "".equals(key)?(null != invocation.getArguments() && invocation.getArguments().length != 0?invocation.getArguments()[0]:""):this.evaluator.key(key, invocation.getMethod(), this.createEvaluationContext(invocation, ExpressionEvaluator.NO_RESULT));
}
private EvaluationContext createEvaluationContext(MethodInvocation invocation, Object result) {
Class targetClass = AopProxyUtils.ultimateTargetClass(invocation.getThis());
if(targetClass == null && invocation.getThis() != null) {
targetClass = invocation.getThis().getClass();
}
return this.evaluator.createEvaluationContext(invocation.getMethod(), invocation.getArguments(), invocation.getThis(), targetClass, result);
}
public Object invoke(MethodInvocation invocation) throws Throwable {
Annotation[] annotations = invocation.getMethod().getAnnotations();
if(null != annotations && annotations.length > 0) {
Cacheable cacheable = (Cacheable)invocation.getMethod().getAnnotation(Cacheable.class);
CacheEvict evict = (CacheEvict)invocation.getMethod().getAnnotation(CacheEvict.class);
if(null == cacheable && null == evict) {
return invocation.proceed();
} else {
Object obj;
Object key;
if(null != cacheable) {
key = this.generateKey(cacheable.key(), invocation);
obj = RedisUtils.get(cacheable.value() + key.toString(), invocation.getMethod().getReturnType());
if(null == obj) {
obj = invocation.proceed();
if(null != obj) {
RedisUtils.set(cacheable.value() + key, obj, cacheable.expireSeconds());
}
}
return obj;
} else if(null != evict) {
key = this.generateKey(evict.key(), invocation);
if(evict.beforeInvocation()) {
RedisUtils.del(evict.value() + key);
}
obj = invocation.proceed();
if(!evict.beforeInvocation()) {
RedisUtils.del(evict.value() + key);
}
if(null != obj && evict.cacheAgain()) {
RedisUtils.set(evict.value() + key, obj, evict.expireSeconds());
}
return obj;
} else {
return invocation.proceed();
}
}
} else {
return invocation.proceed();
}
}
}
3,spring配置:
具体类实现参看文尾:《附录:redis相关类》
<bean id="redisPoolConfig" class="com.~~.cache.redis.RedisPoolConfig">
<property name="maxActive" value="3024"/>
<property name="maxIdle" value="120"/>
<property name="minIdle" value="10"/>
<property name="maxWait" value="3000"/>
<property name="timeOut" value="30000"/>
</bean>
<bean id="redisDataSource" class="com.el.cache.redis.RedisDataSource">
<constructor-arg index="0" value="192.168.~~.~~"/>
<constructor-arg index="1" value="~~~9"/>
<constructor-arg index="2" value=""/>
<constructor-arg index="3" value=""/>
<constructor-arg index="4" value="12"/>
<constructor-arg index="5" ref="redisPoolConfig"/>
</bean>
<bean id="redisClient" class="com.~~.cache.redis.RedisClient">
<property name="dataSource" ref="redisDataSource"/>
</bean>
<bean class="com.~~.cache.redis.utils.RedisUtils">
<property name="redisClient" ref="redisClient"/>
</bean>
<bean id="cacheInterceptor" class="com.~~.cache.redis.interceptor.CacheInterceptor"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>cacheInterceptor</value>
</list>
</property>
</bean>
二,具体应用:
public interface IUserAreaFranchiseeService {
<span style="color:#ff6600;"> <span style="background-color: rgb(192, 192, 192);"> @Cacheable(value = RedisKeyUtils.USER_AREA_ID, expireSeconds = RedisKeyUtils.USER_AREA_ID_TIME)</span></span>
public Integer getUserAreaIdByUid(Integer uid);
}
总结:
在程序的道路上,我们发现,我们有很多重复发明轮子的过程,这是个不可或缺的过程,纵观现代工业的发展史,在最初的蒸汽机时代,没有统一的标准,大家各自为政,在巨大利益的诱惑面前,一系列资本涌入,开始打天下,制定标准,最后,一定是“最合适”的企业生存了,映射到现在,不也是一样吗?
java在制定标准,各种民间资本在各自领域抢占高地