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