spring AOP切面日志
生活随笔
收集整理的這篇文章主要介紹了
spring AOP切面日志
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
spring AOP切面日志
導入依賴
<properties><fastjson.version>1.2.49</fastjson.version> </properties> <!-- spring-boot aop依賴配置引入 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency>文件目錄
切面日志可以自己創建注解,也可以不創建注解,我寫的是創建注解的。
創建注解
/*** 自定義注釋* @author : charry* @date : 2020/10/28 16:58*/ //@OperationLogDetail(detail = "通過手機號[{{tel}}]獲取用戶名",level = 3,operationUnit = OperationUnit.USER,operationType = OperationType.SELECT) @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface OperationLogDetail {/*** 方法描述,可使用占位符獲取參數:{{tel}}*/String detail() default "";/*** 日志等級:自己定,此處分為1-9*/int level() default 0;/*** 操作類型(enum):主要是select,insert,update,delete*/OperationType operationType() default OperationType.UNKNOWN;/*** 被操作的對象(此處使用enum):可以是任何對象,如表名(user),或者是工具(redis)*/OperationUnit operationUnit() default OperationUnit.UNKNOWN; }dao層
/*** 日志記錄對象* @author : charry* @date : 2020/10/28 17:01*/ public class OperationLog {private String id;private Date createTime;/*** 日志等級*/private Integer level;/*** 被操作對象*/private String operationUnit;/*** 方法名*/private String method;/*** 參數*/private String args;/*** 操作人id*/private String userId;/*** 操作人*/private String userName;/*** 日志描述*/private String describe;/*** 操作類型*/private String operationType;/*** 方法運行時間*/private Long runTime;/*** 方法返回值*/private String returnValue;public String getId() {return id;}public void setId(String id) {this.id = id;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime = createTime;}public Integer getLevel() {return level;}public void setLevel(Integer level) {this.level = level;}public String getOperationUnit() {return operationUnit;}public void setOperationUnit(String operationUnit) {this.operationUnit = operationUnit;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getArgs() {return args;}public void setArgs(String args) {this.args = args;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getDescribe() {return describe;}public void setDescribe(String describe) {this.describe = describe;}public String getOperationType() {return operationType;}public void setOperationType(String operationType) {this.operationType = operationType;}public Long getRunTime() {return runTime;}public void setRunTime(Long runTime) {this.runTime = runTime;}public String getReturnValue() {return returnValue;}public void setReturnValue(String returnValue) {this.returnValue = returnValue;}@Overridepublic String toString() {return "OperationLog{" +"id='" + id + '\'' +", createTime=" + createTime +", level=" + level +", operationUnit='" + operationUnit + '\'' +", method='" + method + '\'' +", args='" + args + '\'' +", userId='" + userId + '\'' +", userName='" + userName + '\'' +", describe='" + describe + '\'' +", operationType='" + operationType + '\'' +", runTime=" + runTime +", returnValue='" + returnValue + '\'' +'}';} }操作類型(enum)
/*** @author : charry* @date : 2020/10/28 17:00*/ public enum OperationType {/*** 操作類型*/UNKNOWN("unknown"),DELETE("delete"),SELECT("select"),UPDATE("update"),INSERT("insert");private String value;public String getValue(){return value;}public void setValue(String value){this.value=value;}OperationType(String s){this.value=s;} }被操作的對象(此處使用enum)
/*** 被操作的單元* @author : charry* @date : 2020/10/28 17:00*/ public enum OperationUnit {/*** 被操作的單元*/UNKNOWN("unknown"),USER("user"),EMPLOYEE("employee"),Redis("redis");private String value;OperationUnit(String value){this.value=value;}public String getValue() {return value;}public void setValue(String value) {this.value = value;} }Service層
/*** @author : charry* @date : 2020/10/28 17:01*/ public interface UserService {/*** 獲取用戶信息* @return* @param tel*/String findUserName(String tel); }ServiceImpl層
/*** @author : charry* @date : 2020/10/28 17:02*/ @Service public class UserServiceImpl implements UserService {@OperationLogDetail(detail = "通過手機號[{{tel}}]獲取用戶名",level = 3,operationUnit = OperationUnit.USER,operationType = OperationType.SELECT)@Overridepublic String findUserName(String tel) {System.out.println("tel:" + tel);return "zhangsan";} }Controller
@Controller @RequestMapping("user") public class UserController {@Autowiredprivate UserService userService;/*** 訪問路徑 http://localhost:11000/user/findUserNameByTel?tel=1234567* @param tel 手機號* @return userName*/@ResponseBody@RequestMapping("/findUserNameByTel")public String findUserNameByTel(@RequestParam("tel") String tel){return userService.findUserName(tel);}public static void main(String[] args) {} }LogAspect(切面類)
@Aspect @Component public class LogAspect {/*** 此處的切點是注釋的方式,也可以用包名的方式達到相同的效果* '@Pointcut("execution(* com.wwj.springboot.service.impl.*.*(..))")'*/@Pointcut("@annotation(com.example.springaop.annotation.OperationLogDetail)")public void operationLog(){}/*** 環繞增強,相當于MethodInterceptor*/@Around("operationLog()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{Object res=null;long time=System.currentTimeMillis();try {res=joinPoint.proceed();time=System.currentTimeMillis()-time;return res;}finally {try {//方法執行完成后增加日志addOperationLog(joinPoint,res,time);}catch (Exception e){System.out.println("LogAspect 操作失敗:"+e.getMessage());e.printStackTrace();}}}public void addOperationLog(JoinPoint joinPoint,Object res,long time){MethodSignature signature=(MethodSignature) joinPoint.getSignature();OperationLog operationLog=new OperationLog();operationLog.setRunTime(time);operationLog.setReturnValue(JSON.toJSONString(res));operationLog.setId(UUID.randomUUID().toString());operationLog.setArgs(JSON.toJSONString(joinPoint.getArgs()));operationLog.setCreateTime(new Date());operationLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());operationLog.setUserId("#{currentUserId}");operationLog.setUserName("#{currentUserName}");OperationLogDetail annotation=signature.getMethod().getAnnotation(OperationLogDetail.class);if (annotation != null){operationLog.setLevel(annotation.level());operationLog.setDescribe(getDetail(((MethodSignature)joinPoint.getSignature()).getParameterNames(),joinPoint.getArgs(),annotation));operationLog.setOperationType(annotation.operationType().getValue());operationLog.setOperationUnit(annotation.operationUnit().getValue());}//TODO 這里保存日志System.out.println("記錄日志:"+operationLog.toString());//operationLogService.insert(operationLog);}/*** 對當前登錄用戶和占位符處理* @param argNames 方法參數名稱數組* @param args 方法參數數組* @param annotation 注解信息* @return 返回處理后的描述*/private String getDetail(String[] argNames,Object[] args,OperationLogDetail annotation){Map<Object,Object> map=new HashMap<>(4);for (int i = 0; i <argNames.length ; i++) {map.put(argNames[i],args[i]);}String detail=annotation.detail();try {detail="'"+"#{currentUserName}"+"'=》"+annotation.detail();for (Map.Entry<Object,Object> entry:map.entrySet()){Object k=entry.getKey();Object v=entry.getValue();detail=detail.replace("{{"+k+"}}",JSON.toJSONString(v));}}catch (Exception e){e.printStackTrace();}return detail;}/*** 進入方法前執行* @param joinPoint*/@Before("operationLog()")public void doBeforeAdvice(JoinPoint joinPoint){System.out.println("進入方法前執行....");}/*** 處理完請求,返回內容* @param ret*/@AfterReturning(returning = "ret",pointcut = "operationLog()")public void doAfterReturning(Object ret){System.out.println("方法的返回值:"+ret);}/*** 后置異常通知*/@AfterThrowing("operationLog()")public void throwss(JoinPoint jp){System.out.println("方法異常時執行.....");}/*** 后置最終通知,final增強,不管是拋出異常或者正常退出都會執行*/@After("operationLog()")public void after(JoinPoint jp){System.out.println("方法最后執行.....");} }運行
結論
總結
以上是生活随笔為你收集整理的spring AOP切面日志的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多一些不为什么的坚持,少一些功利主义的追
- 下一篇: 对于幸福不是悖论的证明,在现代对于幸福探