自定义AOP处理业务我一般都是使用的注解+切面的形式,以日志处理简单举个例子就明白了:
定义一个日志注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogOperation {
String value() default "";
}
关于这个注解不用多解释了吧:
@Target(ElementType.METHOD) 方法级别的注解
@Retention(RetentionPolicy.RUNTIME) 运行时级别注解
@Documented 可以被加载到doc文档中
如果有对注解不懂的可以看:
https://blog.csdn.net/qq1404510094/article/details/80577555
定义一个AOP切面:
@Aspect
@Component
public class LogOperationAspect {
@Autowired
private SysESUtils esUtils;
//切点定位在我们写的注解
@Pointcut("@annotation(com.jack.LogOperation)")
public void logPointCut() {
}
//环绕处理
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
try {
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志,枚举就是一个成功标志
saveLog(point, time, LogStatusEnum.SUCCESS.value());
return result;
}catch(Exception e) {
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveLog(point, time, LogStatusEnum.FAIL.value());
throw e;
}
}
//保存日志处理方法
private void saveLog(ProceedingJoinPoint joinPoint, long time, Integer status) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
LogOperation annotation = method.getAnnotation(LogOperation.class);
LogEntity log = new LogEntity();
if(annotation != null){
//注解上的描述
log.setOperation(annotation.value());
}
//请求相关信息
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.setIp(IpUtils.getIpAddr(request));
log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
log.setRequestUri(request.getRequestURI());
log.setRequestMethod(request.getMethod());
//请求参数
Object[] args = joinPoint.getArgs();
try{
String params = JSON.toJSONString(args[0]);
log.setRequestParams(params);
}catch (Exception e){
}
/*这里是用户信息填充,根据自己使用的权限框架获取用户*/
log.setUser(XXXXUtils.getUserId());
//成功失败标志
log.setStatus(status);
//请求处理时间
log.setRequestTime((int)time);
//保存到数据库,一般日志的数量随便一搞就百万起步,所以这里是保存到了ES中
//index为log type分操作日志,系统日志,异常日志
//没有的可以直接保存到MySQL数据库中
esUtils.save(ElasticType.LOG,LogType.OPERATION,log)
}
}
使用注解:
在需要处理的方法上加上自定义日志注解
@PutMapping
@LogOperation("修改Dmoe数据")
public Result update(@RequestBody Demo demo){
return demoService.update(demo);
}
就这么简答,So Easy !!!