自定义注解+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 {
//业务处理请求之前被调用
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("请求前:进入拦截器");
return true;
}
//业务处理请求完成之后。生成视图之前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("请求后:进入拦截器");
afterCompletion(request,response,modelAndView,new Exception());
}
//完全处理完请求之后被调用-可用于清理资源
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("清理资源:进入拦截器");
}
}
/**
* 配置拦截器
* @author zy
*/
@Configuration
public class UserInterceptor implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserRoleAuthorizationInterceptor());
}
}
测试