AOP实现日志打印
package com.youmu.framework.love.interfaces; import java.lang.annotation.*; /** * @Author: guodong * @CreateTime: 2023-04-19 16:38 * @Description: 自定义注解日志类 * @Version: 1.0 */ @Documented @Target(ElementType.METHOD)//注解的作用类型为方法 @Retention(RetentionPolicy.RUNTIME)//注解可在运行阶段被加载到Class对象中 public @interface SysLog { boolean isPrint() default false; /** * 日志等级:自己定,此处分为1-9 */ int level() default 0; /** * 方法描述,可使用占位符获取参数:{{tel}} */ String detail() default ""; }
package com.youmu.framework.love.dtos; import lombok.Data; import java.util.Date; /** * @Author: guodong * @CreateTime: 2023-04-19 16:59 * @Description: TODO * @Version: 1.0 */ @Data 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; }
package com.youmu.framework.love.config; import com.alibaba.fastjson.JSON; import com.youmu.framework.love.dtos.OperationLog; import com.youmu.framework.love.interfaces.SysLog; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.util.*; /** * @Author: guodong * @CreateTime: 2023-04-19 16:48 * @Description: 打印日志信息 * @Version: 1.0 */ @Aspect @Component @Slf4j public class SysLogAop { /** * 此处的切点是注解的方式,也可以用包名的方式达到相同的效果 */ @Pointcut("execution(* com.youmu.framework.love.controller.*.*(..))") 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; } catch (Exception e) { log.error(">> doAround error:{}", e.getMessage(), e); } finally { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); SysLog sysLog = signature.getMethod().getAnnotation(SysLog.class); if (sysLog != null && sysLog.isPrint()) { addOperationLog(joinPoint, res, time); } else { res = joinPoint.proceed(); } } return res; } private 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}"); SysLog annotation = signature.getMethod().getAnnotation(SysLog.class); if (annotation != null) { operationLog.setLevel(annotation.level()); operationLog.setDescribe(getDetail(((MethodSignature) joinPoint.getSignature()).getParameterNames(), joinPoint.getArgs(), annotation)); } log.info(">> addOperationLog:{}", operationLog); } /** * 对当前登录用户和占位符处理 * * @param argNames 方法参数名称数组 * @param args 方法参数数组 * @param annotation 注解信息 * @return 返回处理后的描述 */ private String getDetail(String[] argNames, Object[] args, SysLog annotation) { Map<Object, Object> map = new HashMap<>(); 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; } }
@SysLog(isPrint = true, level = 0, detail = "获取推荐列表") public ResultMessage<List<RecommendResponseVO>> getRecommendList(@RequestBody RecommendRequestVO requestVO) { log.info(">> getRecommendList params:{}", JSONObject.toJSONString(requestVO)); List<RecommendResponseVO> recommendResponseVOList = Lists.newArrayList(); String result = ""; try { result = HttpUtils.postData(url, null, JSONObject.toJSONString(requestVO)); log.info(">> getRecommendList result:{}", result); recommendResponseVOList = JSONObject.parseArray(result, RecommendResponseVO.class); } catch (Exception e) { log.error(">> getRecommendList error:{}", e.getMessage(), e); } return new ResultMessage<>(recommendResponseVOList); }
springboot项目中使用AOP实现日志打印。
郭慕荣博客园