需求:系統中經常需要記錄員工的操作日志和用戶的活動日志,簡單的做法在每個需要的方法中進行日志保存操作,
但這樣對業務代碼入侵性太大,下面就結合AOP和自定義日志注解實現更方便的日志記錄
首先看下一個簡單的操作日志表
action_log
- id
- subject(日志主題)
- content(日志內容)
- create_by
- create_time
日志主題可以用下面的枚舉類來實現
package cn.bounter.common.model; /** * 應用日志主題枚舉類 * @author simon * */ public enum AppLogSubjectEnum { /** 客戶 */ CUSTOMER(1,"客戶"), /** 商品 */ COMMODITY(2,"商品"), /** 訂單 */ ORDER(3,"訂單"); private Integer value; private String name; private AppLogSubjectEnum(int value, String name) { this.value = value; this.name = name; } public Integer getValue() { return value; } public String getName() { return name; } /** * 自定義方法 * 根據枚舉值獲取枚舉字符串內容 * @param value * @return */ public static String stringOf(int value) { for(AppLogSubjectEnum oneEnum : AppLogSubjectEnum.values()) { if(oneEnum.value == value) { return oneEnum.getName(); } } return null; } }
然后讓我們看下自定義注解
package cn.bounter.common.model; import java.lang.annotation.*; /** * 應用日志注解 */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AppLog { /** * 日志主題 * @return */ AppLogSubjectEnum subject(); /** * 日志內容 * @return */ String content() default ""; }
接下來就是重頭戲基於自定義注解的切面了
package cn.bounter.common.model; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.lang.reflect.Method; import java.time.LocalDateTime; /** * 應用日志切面 */ @Aspect @Component public class AppLogAspect { @Autowired private ActionLogService actionLogService; @Pointcut("@annotation(cn.bounter.common.model.AppLog)") public void appLogPointCut() { } @AfterReturning("appLogPointCut()") public void addActionLog(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); //獲取注解 AppLog appLog = method.getAnnotation(AppLog.class); if (appLog == null) { return; } //保存數據庫 actionLogService.save( new ActionLog() .setSubject(appLog.subject().getValue()) .setContent(appLog.content()) .setCreateBy(ShiroUtils.getUser()) //獲取當前登錄的用戶 .setCreateTime(LocalDateTime.now()) ); } }
到這里就差不多,最后讓我們看下怎么使用自定義日志注解
/** * 新增訂單 * @param order * @return */ @AppLog(subject = AppLogSubjectEnum.ORDER, content = "新增") public void save(Order order) { orderService.save(order); }
看完了之后是不是覺得挺簡單哉!那就趕快自己動手試一試吧!