SpringBoot@Aspect 打印訪問請求和返回數據方式
SpringBoot@Aspect 打印訪問請求和返回數據
為什么要用aspect, 使用aspect 可以使記錄日志的功能面向切面,這樣可以降低代碼的耦合性。提供了兩種方式對輸入輸出的數據進行打日志,如下:
aspect:第一種方式
@Before 和 @AfterReturning 來對 controller 進行切面。

輸出數據:

aspect:第二種方式
@Around 來對controller 進行切面。

輸出數據:

兩種方法都是能夠對請求數據做日志監(jiān)控。
第一種方式和第二種方式有一些不同,第二種方式使用的是@Around 環(huán)繞的方式去做的處理,joinPoint.proceed()返回數據需要等方法執(zhí)行完才能執(zhí)行下面的代碼,這種是阻塞式的請求,所以個人建議還是采用第一種方法比較合適。
SpringBoot @Aspect注解詳情
1、添加maven依賴注解
<!--springBoot的aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、添加AOP類
@Component
@Aspect
public class JournalServiceAspect {
}
3、設置切面點
/**切面點*/
private final String POINT_CUT = "execution(* com.xx.xx..*(..))";
@Pointcut(POINT_CUT)
private void pointcut(){}
4、配置前置通知
/**
* 前置通知,方法調用前被調用
* @param joinPoint
*/
@Before(value = POINT_CUT)
public void before(JoinPoint joinPoint){
logger.info("前置通知");
//獲取目標方法的參數信息
Object[] obj = joinPoint.getArgs();
//AOP代理類的信息
joinPoint.getThis();
//代理的目標對象
joinPoint.getTarget();
//用的最多 通知的簽名
Signature signature = joinPoint.getSignature();
//代理的是哪一個方法
logger.info("代理的是哪一個方法"+signature.getName());
//AOP代理類的名字
logger.info("AOP代理類的名字"+signature.getDeclaringTypeName());
//AOP代理類的類(class)信息
signature.getDeclaringType();
//獲取RequestAttributes
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
//從獲取RequestAttributes中獲取HttpServletRequest的信息
HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
//如果要獲取Session信息的話,可以這樣寫:
//HttpSession session = (HttpSession) requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);
//獲取請求參數
Enumeration<String> enumeration = request.getParameterNames();
Map<String,String> parameterMap = Maps.newHashMap();
while (enumeration.hasMoreElements()){
String parameter = enumeration.nextElement();
parameterMap.put(parameter,request.getParameter(parameter));
}
String str = JSON.toJSONString(parameterMap);
if(obj.length > 0) {
logger.info("請求的參數信息為:"+str);
}
}
**注意:這里用到了JoinPoint和RequestContextHolder。
1)、通過JoinPoint可以獲得通知的簽名信息,如目標方法名、目標方法參數信息等。
2)、通過RequestContextHolder來獲取請求信息,Session信息。**
5、配置后置返回通知
/**
* 后置返回通知
* 這里需要注意的是:
* 如果參數中的第一個參數為JoinPoint,則第二個參數為返回值的信息
* 如果參數中的第一個參數不為JoinPoint,則第一個參數為returning中對應的參數
* returning:限定了只有目標方法返回值與通知方法相應參數類型時才能執(zhí)行后置返回通知,否則不執(zhí)行,
* 對于returning對應的通知方法參數為Object類型將匹配任何目標返回值
* @param joinPoint
* @param keys
*/
@AfterReturning(value = POINT_CUT,returning = "keys")
public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys){
logger.info("第一個后置返回通知的返回值:"+keys);
}
@AfterReturning(value = POINT_CUT,returning = "keys",argNames = "keys")
public void doAfterReturningAdvice2(String keys){
logger.info("第二個后置返回通知的返回值:"+keys);
}
6、后置異常通知
/**
* 后置異常通知
* 定義一個名字,該名字用于匹配通知實現方法的一個參數名,當目標方法拋出異常返回后,將把目標方法拋出的異常傳給通知方法;
* throwing:限定了只有目標方法拋出的異常與通知方法相應參數異常類型時才能執(zhí)行后置異常通知,否則不執(zhí)行,
* 對于throwing對應的通知方法參數為Throwable類型將匹配任何異常。
* @param joinPoint
* @param exception
*/
@AfterThrowing(value = POINT_CUT,throwing = "exception")
public void doAfterThrowingAdvice(JoinPoint joinPoint,Throwable exception){
//目標方法名:
logger.info(joinPoint.getSignature().getName());
if(exception instanceof NullPointerException){
logger.info("發(fā)生了空指針異常!!!!!");
}
}
7、后置最終通知
/**
* 后置最終通知(目標方法只要執(zhí)行完了就會執(zhí)行后置通知方法)
* @param joinPoint
*/
@After(value = POINT_CUT)
public void doAfterAdvice(JoinPoint joinPoint){
logger.info("后置最終通知執(zhí)行了!!!!");
}
8、環(huán)繞通知
/**
* 環(huán)繞通知:
* 環(huán)繞通知非常強大,可以決定目標方法是否執(zhí)行,什么時候執(zhí)行,執(zhí)行時是否需要替換方法參數,執(zhí)行完畢是否需要替換返回值。
* 環(huán)繞通知第一個參數必須是org.aspectj.lang.ProceedingJoinPoint類型
*/
@Around(value = POINT_CUT)
public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
logger.info("環(huán)繞通知的目標方法名:"+proceedingJoinPoint.getSignature().getName());
try {
Object obj = proceedingJoinPoint.proceed();
return obj;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
使用RocketMQTemplate發(fā)送帶tags的消息
這篇文章主要介紹了使用RocketMQTemplate發(fā)送帶tags的消息,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
如何為?Spring?Boot?項目配置?Logback?日志
由于?Spring?Boot?的默認日志框架選用的?Logback,再加上?Log4j2?之前爆過嚴重的漏洞,所以我們這次就只關注?Logback,本文重點給大家介紹如何為?Spring?Boot?項目配置?Logback?日志,感興趣的朋友跟隨小編一起看看吧2024-07-07

