SpringBoot自定義注解之實(shí)現(xiàn)AOP切面日志詳解
通過(guò)自定義注解的方式(如:@SysLog(obj = "操作對(duì)象", text = "操作內(nèi)容"),在 SpringBoot 中來(lái)實(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 {
?
? ? /**
? ? ?* 操作對(duì)象
? ? ?* **/
? ? 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ù)庫(kù)
? ? ? ? ?* **/
? ? ? ? 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("請(qǐng)求:" + sysLog.text() + " 出現(xiàn)異常");
? ? }
}五、Controller層實(shí)現(xiàn)
@SysLog(obj = "操作對(duì)象", text = "操作內(nèi)容")
@GetMapping("/index")
? ? public String hello() {
// ? ? ? ?int num = 5/0;
// ? ? ? ?System.out.println("執(zhí)行結(jié)果:" + num);
? ? ? ? return "hello word";
? ? }六、測(cè)試

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中創(chuàng)建線程池的幾種方式以及區(qū)別
創(chuàng)建線程池有多種方式,主要通過(guò) Java 的 java.util.concurrent 包提供的 Executors 工具類來(lái)實(shí)現(xiàn),本文給大家介紹了幾種常見(jiàn)的線程池類型及其區(qū)別,并通過(guò)代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-11-11
spring boot項(xiàng)目快速構(gòu)建的全步驟
這篇文章主要給大家介紹了關(guān)于spring boot項(xiàng)目快速構(gòu)建的全步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Spark SerializedLambda錯(cuò)誤的兩種解決方案
這篇文章主要介紹了Spark SerializedLambda錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
java多線程編程之使用thread類創(chuàng)建線程
在Java中創(chuàng)建線程有兩種方法:使用Thread類和使用Runnable接口。在使用Runnable接口時(shí)需要建立一個(gè)Thread實(shí)例2014-01-01
idea使用war以及war exploded的區(qū)別說(shuō)明
本文詳細(xì)解析了war與warexploded兩種部署方式的差異及步驟,war方式是先打包成war包,再部署到服務(wù)器上;warexploded方式是直接把文件夾、class文件等移到Tomcat上部署,支持熱部署,開(kāi)發(fā)時(shí)常用,文章分別列出了warexploded模式和war包形式的具體操作步驟2024-10-10
java實(shí)現(xiàn)微信公眾號(hào)發(fā)送模版消息
這篇文章以訂單推送為例,主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信公眾號(hào)發(fā)送模版消息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
獲取JPEGImageEncoder和JPEGCode這兩個(gè)類的方法
下面小編就為大家?guī)?lái)一篇獲取JPEGImageEncoder和JPEGCode這兩個(gè)類的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07

