需求:如果入参一致的情况下,返回值一致,那么可以给该方法添加缓存。但是,如果挨个添加每次添加都需要开发、测试,浪费大量时间。
解决方案:利用Spring的AOP,自动添加缓存功能
实现步骤:
1、定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface AutoCache {
/**
* 过期时间,单位是秒,默认1分钟
* @return
*/
int expire() default 60;
/**
* 是否延期,如果选择是,每次访问都会续期expire时长
* @return
*/
boolean isDelay() default false;
String version() default "";
}
一共3个参数:
过期时间
是否延期
方法的版本号
2、AOP拦截器
@Aspect
@Component
@Slf4j
public class CacheIntercepter {
public static final String CACHE_KEY_PREFIX = "AUTOCACHE";
@Autowired
private ResultCache resultCache;
@Around("@annotation(com.heping.aopcache.AutoCache)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
AutoCache methodCache = getAnnotation(joinPoint, AutoCache.class);
String cacheKey = getCacheKey(joinPoint);
String version = methodCache.version();
if(version != null && version.length() > 0){
cacheKey = cacheKey + version;
}
Object obj = resultCache.get(cacheKey);
if (obj != null) {
if(methodCache.isDelay()){
resultCache.expire(cacheKey, methodCache.expire());
}
log.info("自动从缓存获取结果,key [{}]", cacheKey);
return obj;
} else {
log.debug("没有命中缓存,key [{}]", cacheKey);
Object result = joinPoint.proceed(joinPoint.getArgs());
if (result == null) {
log.error("从缓存获取到的结果为空,key [{}]", cacheKey);
} else {
resultCache.save(cacheKey, result, methodCache.expire());
}
return result;
}
}
private String getCacheKey(ProceedingJoinPoint joinPoint) {
return Tool.format("{}-{}.{}",
CACHE_KEY_PREFIX,
joinPoint.getSignature().toString().split("\\s")[1],
StringUtils.join(joinPoint.getArgs(), ",")
);
}
private <T extends Annotation> T getAnnotation(ProceedingJoinPoint jp, Class<T> clazz) {
MethodSignature sign = (MethodSignature) jp.getSignature();
Method method = sign.getMethod();
return method.getAnnotation(clazz);
}
}
其中ResultCache是对缓存读写的封装
3、使用例子
@AutoCache( expire = 10 * 60, isDelay = true, version = "v1")
public String getName(String name){
log.info("没有从缓存获取数据");
return "jdtbi say:" + name;
}
每次修改了方法,逻辑改变的时候,我们只需要修改注解上的version的值,那么我们就会自动刷新缓存了
网友评论