tianyunperfect преди 3 години
родител
ревизия
1c7609a6a2

+ 14 - 0
book-server/src/main/java/com/book/server/annotation/CacheFind.java

@@ -0,0 +1,14 @@
+package com.book.server.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD) //注解在方法中使用
+@Retention(RetentionPolicy.RUNTIME) //运行期有效
+public @interface CacheFind {
+    //设定key
+    String key();             // 设定key,用户自己设定
+    //int seconds() default 0;  //可以指定超时时间,也可以不指定
+}

+ 67 - 0
book-server/src/main/java/com/book/server/aspect/CacheAOP.java

@@ -0,0 +1,67 @@
+package com.book.server.aspect;
+
+import com.book.server.annotation.CacheFind;
+import com.book.server.utils.RedisUtil;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+@Component
+@Aspect
+public class CacheAOP {
+    @Autowired
+    private RedisUtil redisUtil;
+
+    /**
+     * AOP缓存实现的业务策略
+     * 1:切入点表达式应该拦截 @CacheFind注解
+     * 2:通知方法: 环绕通知
+     * 注意:
+     * 如果使用环绕通知,这必须在第一个参数的位置添加ProceedingJoinPoint
+     * 完成redis配置  key
+     * <p>
+     * 动态获取注解参数的步骤
+     * 1.@annotation(cacheFind)   切入点表达式要求拦截一个类型为cacheFind注解。
+     * 2.并且利用连接点为参数中的cacheFind赋值
+     */
+    @Around("@annotation(cacheFind)")  //输入的是切入点的表达式
+    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
+        Object result = null;
+        try {
+            //如何获取动态的获取注解中的数据?
+            String prokey = cacheFind.key();
+            //动态的获取方法中的参数
+            String args = Arrays.toString(joinPoint.getArgs());
+            String key = prokey + "::" + args;
+            Object o = redisUtil.get(key);
+            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
+            Class returnClass = methodSignature.getReturnType();
+
+            //3.校验redis中是否有数据,
+            if (o != null) {
+                result = returnClass.cast(o);
+                return result;
+            }
+            synchronized (key) {
+                Object o1 = redisUtil.get(key);
+                if (o1 != null) {
+                    result = returnClass.cast(o1);
+                    return result;
+                }
+                //没缓存,第一次查询数据库
+                result = joinPoint.proceed(); //执行目标方法
+                //将数据保存到redis
+                redisUtil.setWithTime(key, result);
+            }
+            return result;
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
+            throw new RuntimeException(throwable);
+        }
+    }
+}