spring aop
正常执行顺序
@Around
@Before
method
@After
@AfterReturning
带有异常的执行顺序
@Around
@Before
method
@After
@doAfterThrowing
exception
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
package com.hzcf.operation.aspect; import java.util.Arrays; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; /** * Create by hanlin on 2017年11月14日 基于AOP记录controller的行为日志 **/ @Aspect @Component // 加载顺序 需要保证在 spring的事物之前执行,才会进入@AfterThrowing @Order(1) public class ControllerBehaviorAspect { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * ~第一个 * 代表任意修饰符及任意返回值. * ~第二个 * 任意包名 * ~第三个 * 代表任意方法. * ~第四个 * 定义子包 * ~第五个(..) 任意方法 ~ ..匹配任意数量的参数. * 定义拦截规则:拦截com.hzcf.operation.controller包下面的所有类中,有@RequestMapping注解的方法。 */ @Pointcut("execution(* com.hzcf.operation.controller..*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)") public void behaviorLogAspect() { } /** * 使用@Before在切入点开始处切入内容,在进入controller前进入此方法。 * * @param joinPoint */ @Before("behaviorLogAspect()") public void doBefore(JoinPoint joinPoint) { // 接收到请求,记录请求内容 logger.info("@Before"); // ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); // HttpServletRequest request = attributes.getRequest(); // // // 记录下请求内容 // logger.info("URL : " + request.getRequestURL().toString()); // logger.info("HTTP_METHOD : " + request.getMethod()); // logger.info("IP : " + request.getRemoteAddr()); // logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." // + joinPoint.getSignature().getName()); // logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs())); // // 获取所有参数方法一: // Enumeration<String> enu = request.getParameterNames(); // while (enu.hasMoreElements()) { // String paraName = (String) enu.nextElement(); // System.out.println(paraName + ": " + request.getParameter(paraName)); // } } /** * 拦截器具体实现 * * @param joinPoint * @return JsonResult(被拦截方法的执行结果,或需要登录的错误提示。) * @throws Throwable */ @Around("behaviorLogAspect()") // 指定拦截器规则;也可以直接把"execution(*// com.xjj………)"写进这里 public Object Interceptor(ProceedingJoinPoint joinPoint) throws Throwable { logger.info("@Around"); joinPoint.proceed(); // long beginTime = System.currentTimeMillis(); // MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // Method method = signature.getMethod(); // 获取被拦截的方法 // String methodName = method.getName(); // 获取被拦截的方法名 // // Set<Object> allParams = new LinkedHashSet<>(); // 保存所有请求参数,用于输出到日志中 // // logger.info("请求开始,方法:{}", methodName); // // Object result = null; // // Object[] args = joinPoint.getArgs(); // for (Object arg : args) { // logger.debug("arg: {}", arg); // if (arg instanceof Map<?, ?>) { // // 提取方法中的MAP参数,用于记录进日志中 // @SuppressWarnings("unchecked") // Map<String, Object> map = (Map<String, Object>) arg; // allParams.add(map); // } else if (arg instanceof HttpServletRequest) { // HttpServletRequest request = (HttpServletRequest) arg; // // if (isLoginRequired(method)) { // // if (!isLogin(request)) { // // result = new JsonResult(ResultCode.NOT_LOGIN, // // "该操作需要登录!去登录吗?\n\n(不知道登录账号?请联系老许。)", null); // // } // // } // // // 获取query string 或 posted form data参数 // Map<String, String[]> paramMap = request.getParameterMap(); // if (paramMap != null && paramMap.size() > 0) { // allParams.add(paramMap); // } // } else if (arg instanceof HttpServletResponse) { // // do nothing… // } else { // // allParams.add(arg); // } // } // // try { // if (result == null) { // // 一切正常的情况下,继续执行被拦截的方法 // result = joinPoint.proceed(); // } // } catch (Throwable e) { // logger.info("exception: ", e); // // result = new JsonResult(ResultCode.EXCEPTION, "发生异常:" + // // e.getMessage()); // } // // // if (result instanceof JsonResult) { // long costMs = System.currentTimeMillis() - beginTime; // logger.info("{}请求结束,耗时:{}ms", methodName, costMs); // // } return null; } /** * 使用@After在切入点结尾处切入内容 * * @param joinPoint */ @After("behaviorLogAspect()") public void doAfter(JoinPoint joinPoint) { logger.info("@After"); } /** * 使用@AfterReturning在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理) * * @param joinPoint */ @AfterReturning("behaviorLogAspect()") public void doAfterReturning(JoinPoint joinPoint) { // 处理完请求,返回内容 logger.info("@AfterReturning"); } /** * 使用@AfterThrowing 用来处理当切入内容部分抛出异常之后的处理逻辑。 * * @param joinPoint */ @AfterThrowing(pointcut = "behaviorLogAspect()",throwing = "e") public void doAfterThrowing(JoinPoint joinPoint,Throwable e) { e.printStackTrace(); logger.info("@doAfterThrowing"); } } |
©版权声明:本文为【翰林小院】(huhanlin.com)原创文章,转载时请注明出处!
发表评论