为什么80%的码农都做不了架构师?>>>
在开发过程经常需要进行对于入参,出参以及调用的路径等等做个打印记录,现在要说的是用切面做个日志的打印输出。
- 引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
- 接下来就是写切面类(我这里日志引入了lombok,可以改成自己的日志打印LOGGER)
import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; /** * web日志打印 */ @Aspect @Component @Slf4j public class WebLogAspect { /** * 两个..代表所有子目录,最后括号里的两个..代表所有参数 * com.luoy.test 换成自己的包路径 */ @Pointcut("execution( * com.luoy.test..controller.*.*(..))") public void logPointCut() { } /** * 执行前操作 * @param joinPoint */ @Before("logPointCut()") public void doBefore(JoinPoint joinPoint){ // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 log.info("请求地址 : " + request.getRequestURL().toString()); log.info("HTTP METHOD : " + request.getMethod()); log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("参数 : " + Arrays.toString(joinPoint.getArgs())); } /** * 执行后打印日志 * returning的值和doAfterReturning的参数名一致 * @param ret */ @AfterReturning(returning = "ret", pointcut = "logPointCut()") public void doAfterReturning(Object ret) { // 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址) log.info("返回值 : " + ret); } /** * 环绕通知做打印耗时 * 也可以把上面的2个合到这里来 * @param pjp * @return * @throws Throwable */ @Around("logPointCut()") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long startTime = System.currentTimeMillis(); // ob 为方法的返回值 Object ob = pjp.proceed(); log.info("耗时 : " + (System.currentTimeMillis() - startTime)); return ob; } }
- 写个测试类测试下
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/test") public class TestController { @RequestMapping(value = "/test") public String test(String name) { return "hello" + name; } }
- 输入地址localhost:port/test/test?name=luoye
请求地址 : http://localhost:7082/test/test HTTP METHOD : GET CLASS_METHOD : com.luoy.test.controller.TestController.test 参数 : [luoy] 耗时 : 0 返回值 : helloluoy
- 这样就简单方便多了