基於注解和AOP實現的自定義日志系統。只需要兩個類就能實現:
//注解類 //屬性可以根據需要自行添加 @Target({ElementType.TYPE, ElementType.METHOD})//目標是方法 @Retention(RetentionPolicy.RUNTIME)//注解會在class中存在,運行時可通過反射獲取 //@Inherited @Documented public @interface SysLog { /** * 描述 */ String description() default ""; /** * 行為類型 * 1.違規行為;2.異常行為;3 一般行為 */ String behaviourType() default "3"; /** * 日志風險級別 * 1緊急、2重要、3一般、4信息 */ String level() default "4"; }
切面類:
@Aspect//聲明這是一個事務切面 @Slf4j @Component//讓其被spring管理 public class SysLogAspect { @Around("@annotation(sysLog)") @SneakyThrows public void around(ProceedingJoinPoint point, SysLog sysLog) { //-----------環繞通知開始----------- //保存日志的邏輯 Object obj = point.proceed(); //-----------環繞通知結束----------- //根據obj結果更新日志邏輯 } }
測試類:
//測試類 @SysLog(description = "這是一個測試",behaviourType = "1",level = "2") @PostMapping("/test") public String getTest(){ //業務邏輯 //... return "test"; }
方法二
其余一致,切面類做了修改:
@Aspect//聲明這是一個事務切面 @Slf4j @Component//讓其被spring管理 public class SysLogAspect { //聲明切點 @Pointcut("@annotation(com.xx.xx.SysLog)") public void logPointCut(){} //執行的先后順序是 環繞通知開始-->前置通知before-->后置通知after-->環繞通知結束 @Around("logPointCut()") @SneakyThrows public void around(ProceedingJoinPoint point, SysLog sysLog) { //-----------環繞通知開始----------- //ProceedingJoinPoint只能用於環繞通知,此參數寫在前置和后置通知中會報錯 //獲取request、response ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestCOntextHolder.getRequestAttributes(); HttpServletRequest request = servletRequestAttributes.getRequest(); //保存日志的邏輯 //相當於自己寫在controller中的代碼 Object obj = point.proceed(); //-----------環繞通知結束----------- //根據obj結果更新日志邏輯 } //此外還可以加上前置通知 后置通知等 @Before("logPointCut()") public void doBefore(JoinPoint point){ //可通過point獲取方法名和類名 String className = point.getTarget().getClass().getName(); String methodName = point.getSignature().getName(); } @After("logPointCut()") public void doAfter(JoinPoint point){ } }
持續更新!!!