背景阐述:最近项目当中经常用到Redis缓存,但是把Redis缓存代码写在业务代码中感觉耦合度太高,不利于后期进行拓展。因为我就想到了使用AspectJ进行注解反射对方法进行增强。以下是AspectJ的基础知识,大家了解之后再看这篇文章,不然会很懵逼:关于 Spring AOP (AspectJ) 你该知晓的一切_zejian_的博客-CSDN博客_spring的aop
第一步:添加依赖
<!--进行aop增强的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步:撰写自定义注解
注解的知识我在这里就不再赘述了,大家可以自行去了解
@Retention(RetentionPolicy.RUNTIME) // 注解的生命周期
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface RedisCache {
}
第三步:撰写通知类
在这里我使用@annotation这个标记引进我写的注解。@annotation(com.woniu.sk.product.annotation.RedisCache)这句话的意思是有RedisCache这个注解的方法都进行扫描。
代码中这句话代表了原来代码的执行 List proceed = (List) pjp.proceed();
@Configuration
@Aspect
public class MyAspect {
@Autowired
RedisTemplate redisTemplate;
private ObjectMapper objectMapper = new ObjectMapper();
@Around("@annotation(com.woniu.sk.product.annotation.RedisCache)")
public List myAround(ProceedingJoinPoint pjp) throws Throwable {
String key="getPromotionSeckill";
String fromRedisJson = (String) redisTemplate.opsForValue().get(key);
if (fromRedisJson!=null){
LinkedList linkedList = objectMapper.readValue(fromRedisJson, LinkedList.class);
return linkedList;
}
List proceed = (List) pjp.proceed();
String json = objectMapper.writeValueAsString(proceed);
redisTemplate.opsForValue().set(key,json,30, TimeUnit.MINUTES);
return proceed;
}
}
第四步:在想要增强的方法上上注解
注意:注解只能写在实现类上面不能写在接口上面。因为我们是想要把实现类交给spring管理,注入属性的时候,也是把实现类注入。
@RedisCache
@Override
public List<PromotionProductVo> searchPromotionSeckills() {
List<PromotionProductVo> promotionProductVos = promotionSeckillMapper.selectPromotionSeckills(PromotionStatus.START);
return promotionProductVos;
}
测试结果:
缓存成功,程序未从数据库中拿取数据而是从redis中拿取数据并返回。