自定义注解+AOP,实现 进入方法打印参数日志
/*** 定义进入方法前打印日志注解* @author zy*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PrintLog {}
/*** 定义一个切面,在使用@PrintLog注解的方法进行环绕增强通知* @author zy*/
@Component
@Aspect
@Slf4j
public class PrintLogAspect {/*** Around 环绕增强通知** @param joinPoint 连接点,所有方法都属于连接点;但是当某些方法上使用了@PrintLog自定义注解时,* 则其将连接点变为了切点;然后在切点上织入额外的增强处理;切点和其相应的增强处理构成了切面Aspect 。*/@Around(value = "@annotation(com.example.demo.anno.PrintLog)")public Object handlerPrintLog(ProceedingJoinPoint joinPoint) {// 获取方法的名称String methodName = joinPoint.getSignature().getName();// 获取方法入参Object[] param = joinPoint.getArgs();StringBuilder sb = new StringBuilder();for (Object o : param) {sb.append(o + "; ");}log.info("请求ID:{},进入《{}》方法, 参数为: {}", RequestReqId.getReqId(),methodName, sb.toString());Object object = null;// 继续执行方法try {object = joinPoint.proceed();} catch (Throwable throwable) {log.error("请求ID:{},打印日志处理error。。",RequestReqId.getReqId(), throwable);}log.info("请求ID:{},{} 方法执行结束。。",RequestReqId.getReqId(), methodName);return object;}
}
AOP实现进入方法获取参数信息,给该线程注入ID
/*** HTTP 请求响应的 ThreadLocal 类*/
public class RequestReqId {/*** reqId存储的对象 作为前置和后置的流转声明周期存活*/private static final ThreadLocal<String> ReqIdThreadLocalHolder = new NamedThreadLocal("Log reqId");/*** 注入reqId** @param reqId*/public static void setReqId(String reqId) {ReqIdThreadLocalHolder.set(reqId);}/*** 获取存储的 reqId*/public static String getReqId() {return ReqIdThreadLocalHolder.get();}public static void removereqId() {ReqIdThreadLocalHolder.remove();}
}
@Aspect
@Component
@Slf4j
public class Aspects {@Before("execution(* com.example.demo.controller.*.*(..))")public void getRequestID(JoinPoint proceedingjoinpoint) throws Throwable {Object[] args = proceedingjoinpoint.getArgs();System.out.println("aop:进入方法之前:"+ Arrays.toString(args));String uuid = UUID.randomUUID().toString();RequestReqId.setReqId(uuid);}}
自定义拦截器
/*** 自定义拦截器* @author zy*/
public class UserRoleAuthorizationInterceptor implements HandlerInterceptor {//业务处理请求之前被调用@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("请求前:进入拦截器");return true;}//业务处理请求完成之后。生成视图之前@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("请求后:进入拦截器");afterCompletion(request,response,modelAndView,new Exception());}//完全处理完请求之后被调用-可用于清理资源@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("清理资源:进入拦截器");}
}
/*** 配置拦截器* @author zy*/
@Configuration
public class UserInterceptor implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new UserRoleAuthorizationInterceptor());}}
测试