适用场景:如果一次请求需要多次调用另外一个方法(该方法获取到的数据不需要修改,如调用第三方的查询接口)可以缓存该方法的结果,以便在后续线程直接使用该结果
实现原理:缓存数据存放在ThreadLocal变量中,使用aop拦截需要缓存的方法,如果缓存中有该方法的缓存结果则直接返回,如果没有则执行该方法后缓存该方法的结果。
代码如下:
1. aop注解 定义切面
import java.lang.annotation.*;
/**
* 是否启用自定义的 线程缓存
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface CacheAopFitter {
String value() default "";
int timeout() default 10; //缓存时间(单位:秒) 默认10秒
}
2. aop 拦截类 拦截注解的方法
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Slf4j
public class CacheAop {
//控制器切点
@Pointcut("@annotation(com.mcs.cache.democache.aop.CacheAopFitter) || @within(com.mcs.cache.democache.aop.CacheAopFitter)")
public void cachePoint() {
}
@Around("cachePoint()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//生成key
String key = CacheUtils.createKey(joinPoint);
//判断是否存在 如果有这直接返回
if (CacheUtils.containsKey(key)) {
return CacheUtils.getByKey(key);
}
Object result = joinPoint.p