日志拦截AOP,当执行抛异常时@AfterThrowing执行了没效果

2 篇文章 0 订阅
1 篇文章 0 订阅

使用Spring的AOP进行日志记录,对应的代码为

[java] view plain copy
  1. package cn.tiansu.eway.logAop;  
  2.   
  3. import java.lang.reflect.Method;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import javax.inject.Inject;  
  8.   
  9. import org.apache.shiro.SecurityUtils;  
  10. import org.aspectj.lang.JoinPoint;  
  11. import org.aspectj.lang.ProceedingJoinPoint;  
  12. import org.aspectj.lang.annotation.AfterThrowing;  
  13. import org.aspectj.lang.annotation.Around;  
  14. import org.aspectj.lang.annotation.Aspect;  
  15. import org.aspectj.lang.annotation.Pointcut;  
  16. import org.slf4j.Logger;  
  17. import org.slf4j.LoggerFactory;  
  18. import org.springframework.core.Ordered;  
  19. import org.springframework.stereotype.Component;  
  20.   
  21. import cn.tiansu.eway.annotation.SystemLog;  
  22. import cn.tiansu.eway.entity.LogFormMap;  
  23. import cn.tiansu.eway.mapper.LogMapper;  
  24. import cn.tiansu.eway.util.Common;  
  25.   
  26. /** 
  27.  * 切点类 
  28.  * 
  29.  * @author LJN 
  30.  * @since 2015-05-05 Pm 20:35 
  31.  * @version 1.0 
  32.  */  
  33. @Aspect  
  34. @Component  
  35. public class LogAopAction <span style="color:#ff0000;">implements Ordered</span>{  
  36.     // 本地异常日志记录对象  
  37.     private static final Logger logger = LoggerFactory.getLogger(LogAopAction.class);  
  38.     @Inject  
  39.     private LogMapper logMapper;  
  40.   
  41.     // Controller层切点  
  42.     @Pointcut("@annotation(cn.tiansu.eway.annotation.SystemLog)")  
  43.     public void controllerAspect() {  
  44.     }  
  45.   
  46.     /** 
  47.      * 操作异常记录 
  48.      * 
  49.      * @descript 
  50.      * @param point 
  51.      * @param e 
  52.      * @author LJN 
  53.      * @date 2015年5月5日 
  54.      * @version 1.0 
  55.      */  
  56.     @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")  
  57.     public void doAfterThrowing(JoinPoint point, Throwable e) {  
  58.         LogFormMap logForm = new LogFormMap();  
  59.         Map<String, Object> map = null;  
  60.         String user = null;  
  61.         String ip = null;  
  62.         Long start = 0L;  
  63.         Long end = 0L;  
  64.         Long time = 0L;  
  65.         try {  
  66.             ip = SecurityUtils.getSubject().getSession().getHost();  
  67.         } catch (Exception ee) {  
  68.             ip = "无法获取登录用户Ip";  
  69.         }  
  70.         try {  
  71.             map = getControllerMethodDescription(point);  
  72.             // 登录名  
  73.             user = SecurityUtils.getSubject().getPrincipal().toString();  
  74.             if (Common.isEmpty(user)) {  
  75.                 user = "无法获取登录用户信息!";  
  76.             }  
  77.         } catch (Exception ee) {  
  78.             user = "无法获取登录用户信息!";  
  79.         }  
  80.   
  81.         try {  
  82.             start = System.currentTimeMillis();  
  83.             end = System.currentTimeMillis();  
  84.             time = end - start;  
  85.   
  86.             logForm.put("accountName", user);  
  87.             logForm.put("module", map.get("module"));  
  88.             logForm.put("methods", map.get("methods"));  
  89.             logForm.put("description""执行失败,原因:" + e);  
  90.             logForm.put("actionTime", time);  
  91.             logForm.put("userIP", ip);  
  92.             logForm.put("type", map.get("type"));  
  93.             logMapper.addEntity(logForm);  
  94.   
  95.         } catch (Exception e1) {  
  96.             e1.printStackTrace();  
  97.         }  
  98.     }  
  99.   
  100.     /** 
  101.      * 前置通知 用于拦截Controller层记录用户的操作 
  102.      * 
  103.      * @param joinPoint 
  104.      *            切点 
  105.      */  
  106.     @Around("controllerAspect()")  
  107.     public Object doController(ProceedingJoinPoint point) {  
  108.         Object result = null;  
  109.         // 执行方法名  
  110.         String methodName = point.getSignature().getName();  
  111.         String className = point.getTarget().getClass().getSimpleName();  
  112.         LogFormMap logForm = new LogFormMap();  
  113.         Map<String, Object> map = null;  
  114.         String user = null;  
  115.         Long start = 0L;  
  116.         Long end = 0L;  
  117.         Long time = 0L;  
  118.         String ip = null;  
  119.         try {  
  120.             ip = SecurityUtils.getSubject().getSession().getHost();  
  121.         } catch (Exception e) {  
  122.             ip = "无法获取登录用户Ip";  
  123.         }  
  124.         try {  
  125.             // 登录名  
  126.             user = SecurityUtils.getSubject().getPrincipal().toString();  
  127.             if (Common.isEmpty(user)) {  
  128.                 user = "无法获取登录用户信息!";  
  129.             }  
  130.         } catch (Exception e) {  
  131.             user = "无法获取登录用户信息!";  
  132.         }  
  133.         // 当前用户  
  134.         try {  
  135.             map = getControllerMethodDescription(point);  
  136.             // 执行方法所消耗的时间  
  137.             start = System.currentTimeMillis();  
  138.             result = point.proceed();  
  139.             end = System.currentTimeMillis();  
  140.             time = end - start;  
  141.         } catch (Throwable e) {  
  142.             throw new RuntimeException(e);  
  143.         }  
  144.         try {  
  145.             logForm.put("accountName", user);  
  146.             logForm.put("module", map.get("module"));  
  147.             logForm.put("methods", map.get("methods"));  
  148.             logForm.put("type", map.get("type"));  
  149.             logForm.put("description", map.get("description"));  
  150.             logForm.put("actionTime", time.toString());  
  151.             logForm.put("userIP", ip);  
  152.             logMapper.addEntity(logForm);  
  153.             // *========控制台输出=========*//  
  154.             System.out.println("=====通知开始=====");  
  155.             System.out.println("请求方法:" + className + "." + methodName + "()");  
  156.             System.out.println("方法描述:" + map);  
  157.             System.out.println("请求IP:" + ip);  
  158.             System.out.println("=====通知结束=====");  
  159.         } catch (Exception e) {  
  160.             // 记录本地异常日志  
  161.             logger.error("====通知异常====");  
  162.             logger.error("异常信息:{}", e.getMessage());  
  163.         }  
  164.         return result;  
  165.     }  
  166.   
  167.     /** 
  168.      * 获取注解中对方法的描述信息 用于Controller层注解 
  169.      * 
  170.      * @param joinPoint 
  171.      *            切点 
  172.      * @return 方法描述 
  173.      * @throws Exception 
  174.      */  
  175.     @SuppressWarnings("rawtypes")  
  176.     public Map<String, Object> getControllerMethodDescription(  
  177.             JoinPoint joinPoint) throws Exception {  
  178.         Map<String, Object> map = new HashMap<String, Object>();  
  179.         String targetName = joinPoint.getTarget().getClass().getName();  
  180.         String methodName = joinPoint.getSignature().getName();  
  181.         Object[] arguments = joinPoint.getArgs();  
  182.         Class targetClass = Class.forName(targetName);  
  183.         Method[] methods = targetClass.getMethods();  
  184.         for (Method method : methods) {  
  185.             if (method.getName().equals(methodName)) {  
  186.                 Class[] clazzs = method.getParameterTypes();  
  187.                 if (clazzs.length == arguments.length) {  
  188.                     map.put("module", method.getAnnotation(SystemLog.class)  
  189.                             .module());  
  190.                     map.put("methods", method.getAnnotation(SystemLog.class)  
  191.                             .methods());  
  192.                     map.put("type", method.getAnnotation(SystemLog.class)  
  193.                             .type());  
  194.                     String de = method.getAnnotation(SystemLog.class)  
  195.                             .description();  
  196.                     if (Common.isEmpty(de))  
  197.                         de = "执行成功!";  
  198.                     map.put("description", de);  
  199.                     break;  
  200.                 }  
  201.             }  
  202.         }  
  203.         return map;  
  204.     }  
  205.   
  206.     <span style="color:#ff0000;">@Override  
  207.     public int getOrder() {  
  208.         // TODO Auto-generated method stub  
  209.         return 1;  
  210.     }</span>  
  211. }  
当执行正常时,走 @Around;当执行异常时,走@AfterThrowing。结果发现,执行异常时,@AfterThrowing方法正常执行完毕,但是异常日志并没有插入数据表中,插入日志的代码也没报任何错误,遂百度之(http://my.oschina.net/HuifengWang/blog/304188),发现问题所在:

Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字.我们可以通过在@AspectJ的方法中实现org.springframework.core.Ordered 这个接口来定义order的顺序,order 的值越小,说明越先被执行。

当实现Ordered 接口之后,我们自己写的aop在事务介入之前就执行了!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随与博主沟通,第一间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值