代码源地址:https://github.com/haijiao12138/Spring.git
一.首先实现自定义注解@AutowireRedis,实现该注解的方法会自动实现切面
首先引入redis依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
package com.haijiao12138.demo.spring.util;
import java.lang.annotation.*;
/**
* @author haijiao12138
* @date 2021/8/12 20:57
* @description
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AutowireRedis {
}
二.自定义包中实现自定义注解@AutowireRedis
package com.haijiao12138.demo.spring.aop0812.controller;
import com.haijiao12138.demo.spring.util.AutowireRedis;
import com.haijiao12138.demo.spring.util.DataChange;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author: haijiao12138
* @ClassName: AopController
* @description: TODO
* @date: 2021/8/12 19:35
*
*/
@RestController
@RequestMapping("/aop")
public class AopController {
List<Object> list = new ArrayList<>();
@RequestMapping("/data")
@AutowireRedis
public List<Object> test(){
list.add("张三");
list.add("李四");
return list;
}
@RequestMapping("/addData")
@DataChange(name = "AopController")
public List<Object> addData(){
list.add("王五");
list.add("赵六");
return list;
}
}
三.切面类中对切面升级;
package com.haijiao12138.demo.spring.aop0812;
import com.haijiao12138.demo.spring.util.AutowireRedis;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* @author: haijiao12138
* @ClassName: WebAspect
* @description: TODO
* @date: 2021/8/12 19:32
*/
@Aspect
@Component
public class WebAspect {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 切入点,基于注解实现的切入点 加上该注解的都是Aop切面的切入点
* 匹配top.alanlee.template.controller包及其子包下的所有类的所有方法
*/
@Pointcut("@annotation(com.haijiao12138.demo.spring.util.AutowireRedis)")
public void pointCut() {
}
/**
* 环绕通知
* 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
* 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
*
* @param proceedingJoinPoint
*/
@Around("pointCut()")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("----------- 环绕通知 -----------");
Signature signature = proceedingJoinPoint.getSignature();
System.out.println("环绕通知的目标方法名:" + proceedingJoinPoint.getSignature().getName());
String key1 = new StringBuilder().append(signature).toString();
String key = key1.replace(" ", ".");
String s = stringRedisTemplate.opsForValue().get(key);
if (s == null) {//如果在redis中没取到值 将方法的路径作为key 将切面运行结果作为value存入redis中 供下一次查询使用
try {
Object proceed = proceedingJoinPoint.proceed();
stringRedisTemplate.opsForValue().set(key, String.valueOf(proceed));
return proceed;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
//如果第一次在redis中能取到值 s就不为空 直接将s返回
return Arrays.asList(s.replace("[", "").replace("]", "").split(","));
}
}
四:结果展示
页面结果:
redis结果:
redis中查看结果 需要安装redis可视化工具进行查看即可;
项目路径如下: