如何进行数据库和Redis中的数据同步?/ 你在项目的那些地方使用了aop?
答:可以通过Aop操作来实现数据库和Redis中的数据同步。/ 通过Aop操作来实现数据库和Redis中的数据同步。
可以定义一个切面类,通过对控制器下的所有方法进行环绕通知。
数据同步有两种情况
import cn.cnmd.redis.RedisService; import com.alibaba.fastjson2.JSON; 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 org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import java.lang.reflect.Method; import java.time.Duration; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; @Aspect @Component public class RedisCacheAspect { private static Random random = new Random(); @Autowired private RedisService redisService; @Pointcut("execution(* cn.ctmd.electric.*.controller.*(..))") private void pointcut() { } @Around("pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable { Signature signature = pjp.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); String className = method.getDeclaringClass().getSimpleName(); String methodName = method.getName(); if (method.isAnnotationPresent(GetMapping.class)) {// get请求 Object[] args = pjp.getArgs(); String cacheKey = className + "::" + methodName + JSON.toJSONString(args); if (Boolean.TRUE.equals(redisService.hasKey(cacheKey))) { return redisService.get(cacheKey); } else { synchronized (this) { if (Boolean.FALSE.equals(redisService.hasKey(cacheKey))) { Object value = pjp.proceed(); long expireTime = Duration.ofMinutes(5).toMillis() + random.nextInt(1000); redisService.set(cacheKey, value, expireTime, TimeUnit.MILLISECONDS); return value; } else { return redisService.get(cacheKey); } } } } else { if (method.isAnnotationPresent(PostMapping.class) || method.isAnnotationPresent(PutMapping.class) || method.isAnnotationPresent(DeleteMapping.class)) { List list = redisService.scan(className, 50); if (list != null) { redisService.delete(list.toString()); } } } return pjp.proceed(); } } @Aspect public class AspectJAdvice { @Before(value = "execution(* com.qf.spring.aop.service..*(..))") public void before(JoinPoint jp){ Object[] args = jp.getArgs(); //获取方法参数 Signature signature = jp.getSignature(); //获取签名 if(signature instanceof MethodSignature){ //如果签名是方法签名 Method method = ((MethodSignature) signature).getMethod(); //获取方法 String methodName = method.getName(); String className = method.getDeclaringClass().getName(); System.out.println("准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args)); } } @AfterReturning(value = "execution(* com.qf.spring.aop.service..*(..))", returning = "returnValue") public void after(JoinPoint jp, Object returnValue){ Object[] args = jp.getArgs(); //获取方法参数 Signature signature = jp.getSignature(); //获取签名 if(signature instanceof MethodSignature){ //如果签名是方法签名 Method method = ((MethodSignature) signature).getMethod(); //获取方法 String methodName = method.getName(); String className = method.getDeclaringClass().getName(); System.out.println("执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue); } } @AfterThrowing(value = "execution(* com.qf.spring.aop.service..*(..))", throwing = "t") public void exception(JoinPoint jp, Throwable t){ Object[] args = jp.getArgs(); //获取方法参数 Signature signature = jp.getSignature(); //获取签名 if(signature instanceof MethodSignature){ //如果签名是方法签名 Method method = ((MethodSignature) signature).getMethod(); //获取方法 String methodName = method.getName(); String className = method.getDeclaringClass().getName(); System.out.println("执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage()); } } @Around("execution(* com.qf.spring.aop.service..*(..))") public Object around(ProceedingJoinPoint pjp) throws Throwable { Object[] args = pjp.getArgs();//获取方法的参数 Object target = pjp.getTarget(); //获取代理对象 Signature signature = pjp.getSignature(); //获取签名 if(signature instanceof MethodSignature) { //如果签名是方法签名 Method method = ((MethodSignature) signature).getMethod(); //获取被拦截的方法对象 String methodName = method.getName(); String className = method.getDeclaringClass().getName(); try { System.out.println("准备执行方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args)); Object returnValue = method.invoke(target, args); System.out.println("执行完方法:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",得到返回值:" + returnValue); return returnValue; } catch (Throwable t){ System.out.println("执行方法时:" + className + "." + methodName + ",参数:" + Arrays.toString(args) + ",发生了异常:" + t.getMessage()); throw t; } } return null; } }