系统上需要一个需求,在请求的时候直接从redis中获取值返回,并在后台同时更新redis缓存,这种对于系统实时性要求不高的,可以用切面的方法实现。
定义一个注解
定义一个切面
详细代码:
package com.wudiqiang.aspect;
import com.wudiqiang.utils.RedisUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* @Author: 着凉的皮皮虾
* @Date: 2019/11/29 21:59
* @Description:
*/
@Component
@Aspect
public class CacheAspect {
@Autowired
private RedisUtil redisUtil;
//: 监听此注解
@Pointcut("@annotation(com.wudiqiang.annotation.AspectTest)")
public void AspectTest() {
}
@Around(value = "AspectTest()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("进入切面");
Object[] args = joinPoint.getArgs();
//: 查看参数
String key = args[0].toString();
System.out.println(args[0].toString());
Signature signature = joinPoint.getSignature();
MethodSignature sig = (MethodSignature) signature;
Object target = joinPoint.getTarget();
Method method = target.getClass().getMethod(sig.getName(), sig.getParameterTypes());
//: 某方法上是否有某注解
//boolean annotationPresent = method.isAnnotationPresent(AspectTest.class);
if (redisUtil.hasKey(key)) {
//: 如果redis存在此值,直接从redis获取
Object o = redisUtil.get(key);
return o;
}else {
Object proceed = joinPoint.proceed();
redisUtil.set(key, proceed, 100000L);
return proceed;
}
}
}
启动应用
首先我们的redis服务器数据库1现在是什么数据都没有的
并且定义监控的方法返回值如此:
发送请求,获取返回的结果。
修改返回值
此时redis中存在了这条记录
修改返回结果
再次请求仍然是结果修改前的数据,证明没有走方法,直接走的缓存。
改动代码,返回缓存中结果后更新缓存
测试
如果情况符合预期的话,连续两次请求第一次返回“这是一个测试的语句”,第二次返回“改变后的语句”!
重启应用
第一次结果
此时redis中缓存的数据已经变了