首页 > 代码库 > 用aspectJ 做了一次日志

用aspectJ 做了一次日志

1、

Java代码  技术分享

  1. <aspectj.version>1.7.4.RELEASE</aspectj.version>  

  2.   

  3.     <dependency>  

  4.             <groupId>org.aspectj</groupId>  

  5.             <artifactId>aspectjweaver</artifactId>  

  6.             <version>${aspectj.version}</version>  

  7.         </dependency>  

  8.           

  9.         <dependency>  

  10.             <groupId>org.aspectj</groupId>  

  11.             <artifactId>aspectjrt</artifactId>  

  12.             <version>${aspectj.version}</version>  

  13.         </dependency>  

 注意:如果JDK1.7的 必须这里也是1.7+

 

 

2、

Java代码  技术分享

  1. <aop:config proxy-target-class="true"></aop:config>  

  2.     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  

  3.         <property name="securityManager" ref="securityManager"/>  

  4.     </bean>  

  5.       

  6.     <aop:aspectj-autoproxy proxy-target-class="true"/>  

 注意:下载 必须在spring-mvc.xml里面,且有两个aop配置,下面那个是必须的,上面那个可能不是必须的(上面那个应该是spring aop的,如果有aspectJ了,可以不需要)

 

3、AOP类

 

Java代码  技术分享

  1. package com.kingen.aop;  

  2.   

  3. import java.lang.reflect.Method;  

  4.   

  5. import javax.servlet.http.HttpServletRequest;  

  6. import javax.transaction.Transactional;  

  7.   

  8. import org.aspectj.lang.JoinPoint;  

  9. import org.aspectj.lang.annotation.AfterReturning;  

  10. import org.aspectj.lang.annotation.AfterThrowing;  

  11. import org.aspectj.lang.annotation.Aspect;  

  12. import org.aspectj.lang.annotation.Pointcut;  

  13. import org.slf4j.Logger;  

  14. import org.slf4j.LoggerFactory;  

  15. import org.springframework.stereotype.Component;  

  16. import org.springframework.util.Assert;  

  17. import org.springframework.web.context.request.RequestContextHolder;  

  18. import org.springframework.web.context.request.ServletRequestAttributes;  

  19.   

  20. import com.kingen.bean.Log;  

  21. import com.kingen.bean.User;  

  22. import com.kingen.service.log.LogService;  

  23. import com.kingen.util.Constants;  

  24. import com.kingen.util.DateUtils;  

  25. import com.kingen.util.SpringContextHolder;  

  26. import com.kingen.util.StringUtils;  

  27. import com.kingen.util.UserUtils;  

  28.   

  29. /** 

  30.  * 日志AOP 

  31.  *  

  32.  * @author wj 

  33.  * @date 2016-11-16 

  34.  * 

  35.  */  

  36. @Aspect  

  37. @Component  

  38. public class LogAOP {  

  39.   

  40.     private static LogService logService = SpringContextHolder.getBean(LogService.class);  

  41.   下载 

  42.     // 本地异常日志记录对象  

  43.     private Logger logger = LoggerFactory.getLogger(getClass());  

  44.   

  45.     /** 

  46.      * 在所有标注@LogAnnotation的地方切入 

  47.      *  

  48.      * @param joinPoint 

  49.      */  

  50.     @Pointcut("@annotation(com.kingen.aop.LogAnnotation)")  

  51.     public void logAspect() {  

  52.     }  

  53.   

  54.     // @Around(value = "aApplogic() && @annotation(annotation) &&args(object,..)  

  55.     // ", argNames = "annotation,object")  

  56.     // public Object around(ProceedingJoinPoint pj,  

  57.     // LogAnnotation annotation, Object object) throws Throwable {  

  58.     // System.out.println("moduleName:"+annotation.moduleName());  

  59.     // System.out.println("option:"+annotation.option());  

  60.     // pj.proceed();  

  61.     // return object;  

  62.     // }  

  63.   

  64.     /** 

  65.      * 前置通知 用于拦截Controller层记录用户的操作 

  66.      *  

  67.      * @param joinPoint 

  68.      *            切点 

  69.      * @throws Exception 

  70.      */  

  71. //  @Around(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "annotation,object")  

  72. //  public void doAround(ProceedingJoinPoint joinPoint, LogAnnotation annotation, Object object) {  

  73.     //用@Around 会导致controller不执行,不返回页面  

  74.       

  75. //   @After(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "annotation,object")  

  76. //   public void doAfter(JoinPoint joinPoint, LogAnnotation annotation, Object object) {  

  77.       

  78.      @AfterReturning(value = "logAspect() && @annotation(annotation) &&args(object,..) ", argNames = "", returning = "retVal")  

  79.      public void doAfterReturning(JoinPoint joinPoint, LogAnnotation annotation, Object object,  String retVal) {  

  80.   

  81.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())  

  82.                 .getRequest();  

  83.         try {  

  84.             // String title = getAnnotationValue(joinPoint);  

  85.             String title = getAnnotationValue(annotation);  

  86.             saveLog(request, title);  

  87.         } catch (Exception e) {  

  88.             e.printStackTrace();  

  89.             // 记录本地异常日志  

  90.             logger.error("==异常通知异常==");  

  91.             logger.error("异常信息:{}", e.getMessage());  

  92.         }  

  93.     }  

  94.   

  95.     /** 

  96.      * 异常通知 用于拦截service层记录异常日志 

  97.      *  

  98.      * @param joinPoint 

  99.      * @param e 

  100.      */  

  101.     // 方法  catch住异常的话,这里执行不到  

  102. //  @AfterThrowing(pointcut = "logAspect()", throwing = "e")  

  103.     @AfterThrowing(value = "logAspect() && @annotation(annotation) &&args(..) " , throwing = "e")  

  104.     public void doAfterThrowing(JoinPoint joinPoint,  LogAnnotation annotation, Exception e) {  

  105.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())  

  106.                 .getRequest();  

  107.   

  108.         try {  

  109.   

  110. //          String title = getAnnotationValue(joinPoint);  

  111.             String title = getAnnotationValue(annotation);  

  112.             saveLog(request, title, e);  

  113.         } catch (Exception ex) {  

  114.             // 记录本地异常日志  

  115.             logger.error("==异常通知异常==");  

  116.             logger.error("异常信息:{}", ex.getMessage());  

  117.         }  

  118.   

  119.     }  

  120.   下载 

  121.     public static void saveLog(HttpServletRequest request, String title) {  

  122.         saveLog(request, title, null);  

  123.     }  

  124.   

  125.     /** 

  126.      * 保存日志 

  127.      */  

  128.     @Transactional  

  129.     public static void saveLog(HttpServletRequest request, String title, Exception ex) {  

  130.         User user = UserUtils.getCurrentUser();  

  131.         if (user != null && user.getUserId() != null) {  

  132.             Log log = new Log();  

  133.             log.setCreateDate(DateUtils.getDateTime());  

  134.             log.setTitle(title);  

  135.             log.setType(ex == null ? Log.TYPE_ACCESS : Log.TYPE_EXCEPTION);  

  136.             log.setRemoteAddr(StringUtils.getRemoteAddr(request));  

  137.             log.setUserAgent(user.getUsername());  

  138.             // log.setUserAgent(request.getHeader("user-agent"));  

  139.             log.setRequestUri(request.getRequestURI());  

  140.             log.setParams(request.getParameterMap());  

  141.             // 如果有异常,设置异常信息  

  142.             log.setException(ex == null ? null : ex.getMessage());  

  143. //          log.setException(ex == null ? null : Exceptions.getStackTraceAsString(ex));  

  144.             log.setStatus(ex == null ? Constants.StatusEnum.Success.getIndex() : Constants.StatusEnum.Fail.getIndex());  

  145.             // log.setMethod(request.getMethod());  

  146.             // 异步保存日志  

  147.             // new SaveLogThread(log, handler, ex).start();  

  148.             logService.saveLog(log);  

  149.         }  

  150.     }  

  151.   

  152.     /** 

  153.      * 获取注解中对方法的描述信息 用于Controller层注解 

  154.      *  

  155.      * @param joinPoint 

  156.      *            切点 

  157.      * @return 方法描述 

  158.      * @throws Exception 

  159.      */  

  160.     @Deprecated  

  161.     public static String getAnnotationValue(JoinPoint joinPoint) throws Exception {  

  162.         String targetName = joinPoint.getTarget().getClass().getName();  

  163.         String methodName = joinPoint.getSignature().getName();  

  164.         Object[] arguments = joinPoint.getArgs();  

  165.         Class targetClass = Class.forName(targetName);  

  166.         Method[] methods = targetClass.getMethods();  

  167.         String description = "";  

  168.         for (Method method : methods) {  

  169.             if (method.getName().equals(methodName)) {  

  170.                 Class[] clazzs = method.getParameterTypes();  

  171.                 if (clazzs.length == arguments.length) {  

  172.                     String moduleName = method.getAnnotation(LogAnnotation.class).moduleName();  

  173.                     String option = method.getAnnotation(LogAnnotation.class).option();  

  174.                     Assert.hasText(moduleName, "模块名字不应为空");  

  175.                     Assert.hasText(option, "操作名字不应为空");  

  176.                     description = moduleName + "-" + option;  

  177.                     break;  

  178.                 }  

  179.             }  

  180.         }  

  181.         return description;  

  182.     }  

  183.   

  184.     public static String getAnnotationValue(LogAnnotation anno) throws Exception {  

  185.         String moduleName = anno.moduleName();  

  186.         String option = anno.option();  

  187.         Assert.hasText(moduleName, "模块名字不应为空");  

  188.         Assert.hasText(option, "操作名字不应为空");  

  189.         String description = moduleName + "-" + option;  

  190.         return description;  

  191.     }  

  192. }  

 注意这里 @After和 @AfterReturning的区别,总的来说,就是 @After 是无论如何都会执行的,不管有没有异常抛出(这样会导致,在有异常的时候,记录两次日志,after一次、throwing一次);@AfterReturning 在有异常的情况下,不会执行到,因为没有renturn,在retrun之前就throw了。


用aspectJ 做了一次日志