自定义注解 LogAnnotation
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
String module() default "";
String operator() default "";
}
切面
@Component
@Aspect //切面 定义了通知和切点的关系
@Slf4j
public class LogAspect {
@Pointcut("@annotation(com.xiaoduzi.blog.common.aop.LogAnnotation)")
public void pt(){}
//环绕通知
@Around("pt()")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
long beginTime = System.currentTimeMillis();
//执行方法
Object result = joinPoint.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
recordLog(joinPoint, time);
return result;
}
private void recordLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
log.info("=====================log start================================");
log.info("module:{}",logAnnotation.module());
log.info("operation:{}",logAnnotation.operator());
//请求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
log.info("request method:{}",className + "." + methodName + "()");
//请求的参数
Object[] args = joinPoint.getArgs();
String params = JSON.toJSONString(args[0]);
log.info("params:{}",params);
//获取request 设置IP地址
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.info("ip:{}", IpUtils.getIpAddr(request));
//执行时间
log.info("excute time : {} ms",time);
log.info("=====================log end================================");
}
}
自定义Cache
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cache {
//过期时间 缓存标识 key
long expire() default 1 * 60 * 1000;
String name() default "";
}
清除缓存
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface CacheClear {
}
切面
@Aspect
@Component
@Slf4j
public class CacheAspect {
@Autowired
private RedisTemplate<String, String> redisTemplate;
List<String> keys = new ArrayList<>();
@Pointcut("@annotation(com.xiaoduzi.blog.common.cache.Cache)")
public void pt(){}
@Pointcut("@annotation(com.xiaoduzi.blog.common.cache.CacheClear)")
public void clear(){}
@Before("clear()")
public void clear (JoinPoint pjp){
for (String key : keys) {
redisTemplate.delete(key);
}
keys.clear();
System.out.println("清理了缓存————————————————————————————————————————————");
}
@Around("pt()")
public Object around(ProceedingJoinPoint pjp){
try {
Signature signature = pjp.getSignature();
//类名
String className = pjp.getTarget().getClass().getSimpleName();
//调用的方法名
String methodName = signature.getName();
Class[] parameterTypes = new Class[pjp.getArgs().length];
Object[] args = pjp.getArgs();
//参数
String params = "";
for(int i=0; i<args.length; i++) {
if(args[i] != null) {
params += JSON.toJSONString(args[i]);
parameterTypes[i] = args[i].getClass();
}else {
parameterTypes[i] = null;
}
}
if (StringUtils.isNotEmpty(params)) {
//加密 以防出现key过长以及字符转义获取不到的情况
params = DigestUtils.md5Hex(params);
}
Method method = pjp.getSignature().getDeclaringType().getMethod(methodName, parameterTypes);
//获取Cache注解
Cache annotation = method.getAnnotation(Cache.class);
//缓存过期时间
long expire = annotation.expire();
//缓存名称
String name = annotation.name();
//先从redis获取
String redisKey = name + "::" + className+"::"+methodName+"::"+params;
String redisValue = redisTemplate.opsForValue().get(redisKey);
if (StringUtils.isNotEmpty(redisValue)){
log.info("走了缓存~~~,{},{}",className,methodName);
Result result = JSON.parseObject(redisValue, Result.class);
return result;
}
Object proceed = pjp.proceed();
redisTemplate.opsForValue().set(redisKey,JSON.toJSONString(proceed), Duration.ofMillis(expire));
log.info("存入缓存~~~ {},{}",className,methodName);
// 缓存的key存在一个list
keys.add(redisKey);
System.out.println(keys);
return proceed;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return Result.fail(-999,"系统错误");
}
}