AspectWebLog.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package com.emato.ccnet.wx.aop;
  2. import com.fasterxml.jackson.core.JsonProcessingException;
  3. import com.fasterxml.jackson.databind.ObjectMapper;
  4. import org.aspectj.lang.JoinPoint;
  5. import org.aspectj.lang.ProceedingJoinPoint;
  6. import org.aspectj.lang.Signature;
  7. import org.aspectj.lang.annotation.*;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.web.context.request.RequestContextHolder;
  12. import org.springframework.web.context.request.ServletRequestAttributes;
  13. import javax.servlet.http.HttpServletRequest;
  14. import java.util.Collection;
  15. import java.util.Map;
  16. /**
  17. * 日志AOP
  18. * 通过<code>JoinPoint</code>可以获得通知的签名信息,如目标方法名、目标方法参数信息等
  19. * 通过RequestContextHolder来获取<code>HttpServletRequest</code>请求信息,<code>Session</code>Session信息
  20. * @author Scott Chen
  21. * @since 1.0
  22. * 2015-05-13
  23. */
  24. @Aspect
  25. public class AspectWebLog {
  26. private static final Logger logger = LoggerFactory.getLogger(AspectWebLog.class);
  27. @Autowired
  28. ObjectMapper objectMapper;
  29. @Pointcut("execution(* com.emato.ccnet.wx..*.*(..)) " +
  30. "&& @annotation(org.springframework.web.bind.annotation.RequestMapping)" +
  31. "&& !execution(* com.emato.ccnet.wx..aop..*.*(..))")
  32. public void controllerPointcut(){}
  33. /**
  34. * 前置通知
  35. * 执行方法之前执行前置通知方法
  36. * @param jp:JoinPoint
  37. * @return
  38. */
  39. @Before(value="controllerPointcut()")
  40. public void beforeAdvice(JoinPoint jp) {
  41. // 目标方法的参数信息
  42. Object[] args = jp.getArgs();
  43. // AOP代理类的信息
  44. Object objThis = jp.getThis();
  45. // 代理的目标对象
  46. Object objTarget = jp.getTarget();
  47. // 通知的方法签名
  48. Signature signature = jp.getSignature();
  49. // AOP代理类类型
  50. Class proxyClzz = signature.getDeclaringType();
  51. // AOP代理类名
  52. String className = signature.getDeclaringTypeName();
  53. // 代理方法名
  54. String methodName = signature.getName();
  55. // 获取RequestAttributes
  56. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  57. // 从获取RequestAttributes中获取HttpServletRequest的信息
  58. HttpServletRequest request = attributes.getRequest();
  59. //method
  60. logger.debug("--- 请求Method: {}", request.getMethod());
  61. //类方法
  62. logger.debug("--- 调用class: 【{}】, method: 【{}】", className, methodName);
  63. try {
  64. String str = null;
  65. if (args.length > 0) {
  66. if (args[0] instanceof Collection || args[0] instanceof Map) {
  67. str = objectMapper.writeValueAsString(args[0]);
  68. } else {
  69. for(int i=0;i<args.length;i++) {
  70. str += objectMapper.writeValueAsString(args[i]);
  71. if (i < args.length - 1) {
  72. str += ", ";
  73. }
  74. }
  75. }
  76. }
  77. logger.debug("【" + className + "#" + methodName + "】发起请求, 请求参数: {}", str);
  78. } catch (JsonProcessingException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. /**
  83. * 环绕通知
  84. * 主体方法返回后将执行的通知方法
  85. * @param pjp:ProceedingJoinPoint
  86. * @return
  87. */
  88. @Around(value="controllerPointcut()")
  89. public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
  90. String className = pjp.getSignature().getDeclaringTypeName();
  91. String methodName = pjp.getSignature().getName();
  92. long bftime = System.currentTimeMillis();
  93. // 继续执行被拦截的方法
  94. Object retVal = pjp.proceed();
  95. double time =(double)(System.currentTimeMillis() - bftime) / 1000;
  96. logger.info("【" + className + "#" + methodName + "】执行时间: {}秒", time);
  97. return retVal;
  98. }
  99. /**
  100. * 后置通知
  101. * 执行方法之后执行后置通知方法
  102. * @param jp:JoinPoint
  103. * @return
  104. */
  105. @After(value="controllerPointcut()")
  106. public void afterAdvice(JoinPoint jp) {
  107. Object[] args = jp.getArgs();
  108. String className = jp.getSignature().getDeclaringTypeName();
  109. String methodName = jp.getSignature().getName();
  110. try {
  111. String str = null;
  112. if (args.length > 0) {
  113. if (args[0] instanceof Collection || args[0] instanceof Map) {
  114. str = objectMapper.writeValueAsString(args[0]);
  115. } else {
  116. for(int i=0;i<args.length;i++) {
  117. str += objectMapper.writeValueAsString(args[i]);
  118. if (i < args.length - 1) {
  119. str += ", ";
  120. }
  121. }
  122. }
  123. }
  124. logger.info("【" + className + "#" + methodName + "】执行结束, 请求参数: {}", str);
  125. } catch (JsonProcessingException e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. /**
  130. * 返回通知
  131. * 方法执行成功后,调用返回通知,如果方法在运行过程中抛出异常,则不会调用
  132. * @param jp:JoinPoint
  133. * @param retValue:String 主体方法传递到通知方法的返回值
  134. * @return
  135. */
  136. @AfterReturning(value="controllerPointcut()", returning = "retValue")
  137. public void afterReturningAdvice(JoinPoint jp, Object retValue) {
  138. String className = jp.getSignature().getDeclaringTypeName();
  139. String methodName = jp.getSignature().getName();
  140. if (retValue == null) {
  141. logger.info("【" + className + "#" + methodName + "】执行结束, 返回数据: {}");
  142. return;
  143. }
  144. try {
  145. String str = objectMapper.writeValueAsString(retValue);
  146. logger.info("【" + className + "#" + methodName + "】执行结束, 返回数据:{}", str);
  147. } catch (JsonProcessingException e) {
  148. e.printStackTrace();
  149. }
  150. }
  151. /**
  152. * 异常通知
  153. * 方法在运行过程中,如果抛出异常,则执行异常通知
  154. * @param jp:JoinPoint
  155. * @return
  156. */
  157. @AfterThrowing(value="controllerPointcut()", throwing = "ex")
  158. public void afterThrowingAdvice(JoinPoint jp, Exception ex) {
  159. String className = jp.getSignature().getDeclaringTypeName();
  160. String methodName = jp.getSignature().getName();
  161. logger.info("【" + className + "#" + methodName + "】发生异常结束: {}", ex);
  162. }
  163. }