SpringBoot自定義注解之實(shí)現(xiàn)AOP切面日志詳解
通過自定義注解的方式(如:@SysLog(obj = "操作對象", text = "操作內(nèi)容"),在 SpringBoot 中來實(shí)現(xiàn) AOP 切面統(tǒng)一打印出入?yún)⑷罩尽?/p>
一、先看下項(xiàng)目結(jié)構(gòu)

二、Maven JAR依賴
<!-- AOP --> ? ? <dependency> ? ? ? ? ? ? <groupId>org.springframework.boot</groupId> ? ? ? ? ? ? <artifactId>spring-boot-starter-aop</artifactId> </dependency>
三、自定義注解
@SysLog
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
?
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SysLog {
?
? ? /**
? ? ?* 操作對象
? ? ?* **/
? ? String obj() default "";
?
? ? /**
? ? ?* 操作內(nèi)容
? ? ?* **/
? ? String text() default "";
}四、AOP切面
import java.lang.reflect.Method;
?
import com.zxk.demo.annotation.SysLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
?
?
@SuppressWarnings("all")
@Aspect
@Component
public class SysLogAspect {
?
? ? // 切入點(diǎn)
? ? @Pointcut(value = "@annotation(com.zxk.demo.annotation.SysLog)")
? ? private void pointcut() {
? ? }
?
? ? /**
? ? ?* 在方法執(zhí)行前
? ? ?* @param point
? ? ?* @param myLog
? ? ?* @return
? ? ?*/
? ? @Before(value = "pointcut() && @annotation(sysLog)")
? ? public void before(SysLog sysLog){
? ? ? ? System.out.println("++++執(zhí)行了before方法++++");
? ? }
?
?
? ? /**
? ? ?* 在方法執(zhí)行前后
? ? ?* @param point
? ? ?* @param myLog
? ? ?* @return
? ? ?*/
? ? @Around(value = "pointcut() && @annotation(sysLog)")
? ? public Object around(ProceedingJoinPoint point, SysLog sysLog) {
? ? ? ? System.out.println("++++執(zhí)行了around方法++++");
? ? ? ? String obj = sysLog.obj();
? ? ? ? String text = sysLog.text();
? ? ? ? // 攔截的類名
? ? ? ? Class clazz = point.getTarget().getClass();
? ? ? ? // 攔截的方法
? ? ? ? Signature sig = point.getSignature();
? ? ? ? MethodSignature msig = null;
? ? ? ? if (!(sig instanceof MethodSignature)) {
? ? ? ? ? ? throw new IllegalArgumentException("該注解只能用于方法");
? ? ? ? }
? ? ? ? msig = (MethodSignature) sig;
? ? ? ? Object target = point.getTarget();
? ? ? ? Method currentMethod;
? ? ? ? try {
? ? ? ? ? ? currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
? ? ? ? ? ? System.out.println("執(zhí)行了類:" + clazz.getSimpleName());
? ? ? ? ? ? System.out.println("方法:" + currentMethod.getName());
? ? ? ? ? ? System.out.println("自定義注解:" + obj+"==="+text);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? try {
? ? ? ? ? ? return point.proceed(); // 執(zhí)行程序
? ? ? ? } catch (Throwable throwable) {
? ? ? ? ? ? throwable.printStackTrace();
? ? ? ? ? ? return throwable.getMessage();
? ? ? ? }
? ? }
?
? ? /**
? ? ?* 方法執(zhí)行后
? ? ?* @param joinPoint
? ? ?* @param myLog
? ? ?* @param result
? ? ?* @return
? ? ?*/
? ? @AfterReturning(value = "pointcut() && @annotation(sysLog)", returning = "result")
? ? public Object afterReturning(JoinPoint joinPoint, SysLog sysLog, Object result) {
? ? ? ? // HttpServletRequest request = ((ServletRequestAttributes)
? ? ? ? // RequestContextHolder.getRequestAttributes()).getRequest();
? ? ? ? // HttpSession session = request.getSession();
? ? ? ? /**
? ? ? ? ?* 將信息保存到數(shù)據(jù)庫
? ? ? ? ?* **/
? ? ? ? System.out.println("++++執(zhí)行了afterReturning方法++++");
? ? ? ? System.out.println("自定義注解:" + sysLog.obj()+"=="+sysLog.text());
? ? ? ? System.out.println("執(zhí)行結(jié)果:" + result);
? ? ? ? return result;
? ? }
?
? ? /**
? ? ?* 方法執(zhí)行后 并拋出異常
? ? ?* @param joinPoint
? ? ?* @param myLog
? ? ?* @param ex
? ? ?*/
? ? @AfterThrowing(value = "pointcut() && @annotation(sysLog)", throwing = "ex")
? ? public void afterThrowing(JoinPoint joinPoint, SysLog sysLog, Exception ex) {
? ? ? ? System.out.println("++++執(zhí)行了afterThrowing方法++++");
? ? ? ? System.out.println("請求:" + sysLog.text() + " 出現(xiàn)異常");
? ? }
}五、Controller層實(shí)現(xiàn)
@SysLog(obj = "操作對象", text = "操作內(nèi)容")
@GetMapping("/index")
? ? public String hello() {
// ? ? ? ?int num = 5/0;
// ? ? ? ?System.out.println("執(zhí)行結(jié)果:" + num);
? ? ? ? return "hello word";
? ? }六、測試

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java ArrayDeque實(shí)現(xiàn)Stack的功能
這篇文章主要介紹了Java ArrayDeque實(shí)現(xiàn)Stack功能的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-03-03
Flask實(shí)現(xiàn)異步非阻塞請求功能實(shí)例解析
這篇文章主要介紹了Flask實(shí)現(xiàn)異步非阻塞請求功能實(shí)例解析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-02-02
java開發(fā)建造者模式驗(yàn)證實(shí)例詳解
這篇文章主要為大家介紹了java開發(fā)中建造者模式的驗(yàn)證實(shí)例詳解,文中附含詳細(xì)示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
Java模擬實(shí)現(xiàn)HTTP服務(wù)器項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了Java模擬實(shí)現(xiàn)HTTP服務(wù)器項(xiàng)目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
RocketMQ實(shí)現(xiàn)消息分發(fā)的步驟
RocketMQ 實(shí)現(xiàn)消息分發(fā)的核心機(jī)制是通過 Topic、Queue 和 Consumer Group 的配合實(shí)現(xiàn)的,下面給大家介紹RocketMQ實(shí)現(xiàn)消息分發(fā)的步驟,感興趣的朋友一起看看吧2024-03-03
SpringBoot創(chuàng)建多模塊項(xiàng)目的全過程記錄
這篇文章主要給大家介紹了關(guān)于SpringBoot創(chuàng)建多模塊項(xiàng)目的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

