Aop实现日志时,@AfterThrowing执行正常,但数据未提交解决办法
最近开发需使用AOP方式实现系统审计日志,主要功能为方法开始、结束、异常时需要记录日志并存入数据库,实际运行过程中@Around环绕通知可以正常执行,系统抛出异常时,@AfterThrowing异常通知也可正常执行,但记录的数据没有正常提交数据库,查找原因及网上百度,发现问题所在:Spring事务是通过AOP实现的,自己写的AOP与事务AOP存在执行顺序问题,如果事务AOP先执行了,@AfterThrowing中数据则无法提交。解决办法为@Aspect方法实现org.springframework.core .orderd接口或使用@Order注解,推荐使用注解方式。
代码如下:
@Aspect
@Component
public class SystemLogAspect implements Ordered{
@Resource
private SystemLogInfoService systemLogInfoService;
// 切点
@Pointcut("@annotation(com.aop.SystemLog)")
public void SystemLogAspectPoint() {
}
//环绕通知
@Around("SystemLogAspectPoint()")
public void doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
SystemLogInfo systemLogInfo1 = new SystemLogInfo();
SystemLogInfo systemLogInfo2= new SystemLogInfo()
systemLogInfo1.setDescribed("开始");
systemLogInfoService.add(systemLogInfo1);
//执行代理
proceedingJoinPoint.proceed();
systemLogInfo2.setDescribed("结束");
systemLogInfoService.add(systemLogInfo2);
}
//异常抛出通知
@AfterThrowing(value="SystemLogAspectPoint()",throwing = "ex")
public void doAround(JoinPoint joinPoint,Throwable ex) throws Throwable {
SystemLogInfo systemLogInfo = new SystemLogInfo();
systemLogInfo.setDescribed("抛出异常信息:"+ex.getMessage());
systemLogInfoService.add(systemLogInfo);
}
@Override
public int getOrder() {
return 1;
}
}
或者添加@Order注解,不用实现orderd接口,代码如下:
@Aspect
@Order(1)
@Component
public class SystemLogAspect{
@Resource
private SystemLogInfoService systemLogInfoService;
// 切点
@Pointcut("@annotation(com.aop.SystemLog)")
public void SystemLogAspectPoint() {
}
//环绕通知
@Around("SystemLogAspectPoint()")
public void doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
... ... ... ...
}
... ... ... ...
}
推荐使用注解@Order方式。spring配置文件事务需做如下配置:
<!--开启注解数据库事务 优先级2-->
<tx:annotation-driven order = "2"/>
数字越小优先级越高。解决后,自定义AOP在事务之前可以正常执行。
参考博客: https://blog.csdn.net/erica_1230/article/details/51131113