通过注解实现本地缓存caffeine的学习

注解源码如下

1 @Target(ElementType.METHOD)
2 @Retention(RetensionPolicy.RUNTIME)
3 @Documented
4 public @interface RvcCache{
5       Strng key();
6       String id() default StringUtils.EMPTY;
7 }    
 1 @Component
 2 @Aspect
 3 @RequiredArgsConstructor
 4 public class RvcCacheAspect {
 5 
 6     private final CacheUtils cacheUtils;
 7 
 8     private final UserLogUtils userLogUtils;  
 9     /**
10      *  @Around为环绕advice(增强),被RvcCache注解的方法为切入点Pointcut
11      * 使用ProceedingJoinPoint类型作为环绕增强型方法的参数,用于调用被增强的方法
12      * 在以下代码实例中就是获取key和id的值,以及被增强方法return的数据
13      */
14    @Around("@annotation(rvc.core.cache.annotation.RvcCache)")
15     public Object doAround(ProceedingJoinPoint point) throws Throwable {
16         MethodSignature signature = (MethodSignature)point.getSignature();
17         Method method = signature.getMethod();
18         RvcCache annotation = method.getAnnotation(RvcCache.class);
19         //获取key和id
20         String realKey = annotation.key();
21         if (StringUtils.isNotEmpty(annotation.id())) {
22             //拼接解析springEl表达式的map
23             //简单理解这段代码就是将springEl表达式的id值解析成正确的值
24             String[] paramNames = signature.getParameterNames();
25             Object[] args = point.getArgs();
26             TreeMap<String, Object> treeMap = new TreeMap<>();
27             for (int i = 0; i < paramNames.length; i++) {
28                 treeMap.put(paramNames[i], args[i]);
29             }
30             String elResult = ElStringUtils.parse(annotation.id(), treeMap);
31             //id值可为空,如果为空,则缓存对象cache的key为注解的key值,如果不为空,则缓存对象的key为注解"key.id"
32             realKey = annotation.key() + "." + elResult;
33         }
34         //内部方法,获取当前key的值,内部的存储结构为ConcurrentHashMap(Integer, Cache<String, Object>);
35         //Integer为本地缓存的存活时间,自定义的时间,Cache为缓存的对象(内部的缓存工具通过Caffeine.newBuilder().expireAfterWrite(expireTime, TimeUnit.HOURS)来设置存活时间)    
36         //也就是说相同存活时间的缓存对象在同一个map下
37         Cache<String, Object> cache = cacheUtils.getManualCache(realKey);
38         //读写,查询Caffeine,根据处理的key查询,查到则直接返回数据
39         Object object = cache.getIfPresent(realKey);
40         if (Objects.nonNull(object)) {
41             return object;
42         }
43         //没有查询到则获取当前被注解方法执行完后return的数据,并判断这个数据是正确返回的(无异常、无报错)后写入Caffeine,
44         object = point.proceed();
45         if (object instanceof RetParamBase) {
46             RetParamBase ret = (RetParamBase)object;
47             if (!ret.isSucceed()) {
48                 return ret;
49             }
50             //写入Caffeine
51             cache.put(realKey, object);
52         }
53         return object;
54     }
55 }

先弄明白几个概念:

springEl表达式:一种强大,简洁的装配Bean的方式,他可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中,更可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置。在上述注解中id的值可以通过以下方式获取

 

posted @ 2024-02-16 14:40  leviH  阅读(22)  评论(0编辑  收藏  举报