1、添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、添加切面類
package com.example.demo.aop;
import lombok.SneakyThrows;
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;
@Slf4j
@Aspect
@Component
public class LogAspect {
/**
* 可以配置多個切面,來對多個切面做操作,方法名稱爲方法名,並在下邊的before登使用
*
* 非異常順序:@Around中的方法-->@Before->controller-->@Around執行完--> @After-->@AfterReturning
* 異常順序:@Around中的方法-->@Before->controller-->@Around執行完(不捕獲異常)--> @After- @AfterThrowing
*
* 另外發現一個很又有的註解@SneakyThrows
*/
@Pointcut("execution(public * com.example.demo.controller.*.*(..))")
public void webControllerLog(){}
@Pointcut("execution(public * com.example.demo.service.*.*(..))")
public void webServicePractice(){}
@Before("webServicePractice()")
public void deServiceBefore(JoinPoint joinPoint) throws Throwable {
// 接收到請求,記錄請求內容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄下請求內容
log.info("URL : " + request.getRequestURL().toString());
System.out.println("URL : " + request.getRequestURL().toString());
System.out.println("HTTP_METHOD : " + request.getMethod());
System.out.println("IP : " + request.getRemoteAddr());
System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
@Before("webControllerLog()")
public void deBefore(JoinPoint joinPoint) throws Throwable {
// 接收到請求,記錄請求內容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄下請求內容
System.out.println("URL : " + request.getRequestURL().toString());
System.out.println("HTTP_METHOD : " + request.getMethod());
System.out.println("IP : " + request.getRemoteAddr());
System.out.println("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
System.out.println("ARGS : " + Arrays.toString(joinPoint.getArgs()));
}
//後置最終通知,final增強,不管是拋出異常或者正常退出都會執行
@After("webControllerLog()")
public void after(JoinPoint jp){
System.out.println("方法最後執行.....");
}
@AfterReturning(returning = "ret", pointcut = "webControllerLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 處理完請求,返回內容
System.out.println("方法的返回值 : " + ret);
}
//後置異常通知
@AfterThrowing(pointcut = "webControllerLog()",throwing = "ex")
public void throwsMethod(JoinPoint jp){
System.out.println("方法異常時執行.....");
}
// /**
// * 環繞通知,環繞增強,相當於MethodInterceptor
// * ***可以不配置,並建議不配置,
// * 如果不配置直接進入before,異常會被捕獲到,如果處理了異常則不會進入@AfterThrowing,可以使用 throws Throwable拋出,或者使用@SneakyThrows拋出異常
// */
// @SneakyThrows
// @Around("webControllerLog()")
// public Object arround(ProceedingJoinPoint pjp) {
// System.out.println("方法環繞start.....");
//// try {
// // 進入@before
// Object o = pjp.proceed();
// System.out.println("方法環繞proceed,結果是 :" + o);
// return o;
//// // 這個地方如果處理異常,如果發成異常則不會進入@AfterThrowing
//// } catch (Throwable e) {
//// e.printStackTrace();
//// return null;
//// }
// }
}
3、創建一個測試類
package com.example.demo.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* 測試aop
*/
@Slf4j
@Api(tags = "測試aop")
@RestController(value = "/aop")
public class AopController {
@RequestMapping(value = "/aop",method = RequestMethod.GET,produces = "application/json;charset=UTF-8" )
@ApiOperation(value = "測試aop",notes = "。。。")
public String aopMethod(){
log.info("controller層返回的方法");
return "aop方法返回";
}
@RequestMapping(value = "/aopException",method = RequestMethod.GET,produces = "application/json;charset=UTF-8" )
@ApiOperation(value = "測試異常aop捕獲",notes = "。。。")
public int exceptionMethod(){
log.info("aop異常返回的方法");
return 1/0;
}
}
4、結果
URL : http://localhost:8080/aop
HTTP_METHOD : GET
IP : 0:0:0:0:0:0:0:1
CLASS_METHOD : com.example.demo.controller.AopController.aopMethod
ARGS : []
2020-05-10 16:16:04.877 INFO 8692 --- [nio-8080-exec-9] c.example.demo.controller.AopController : controller層返回的方法
方法最後執行.....
方法的返回值 : aop方法返回
具體的注意事項等在代碼中有註釋,此文只是一個簡單的配置沒有解釋