前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、自定义 Pointcut

默认情况下,匹配所有的类,这里配置是否需要拦截

public class CustomStatusPointcut extends StaticMethodMatcherPointcutAdvisor {

  /**
     * 切点方法 匹配
     * 匹配规则: 默认情况下,匹配所有的类
     */
  @Override
  public boolean matches(Method method, Class<?> clazz) {
    return Optional.ofNullable(clazz.getName()).map(item -> item.contains("Controller")).orElse(false);
  }

}

2、自定义 Advice

Pointcut拦截的方式进行切面处理,这个advice就是我们需要执行的切面逻辑

@Slf4j
public class  CustomStatusAdvice implements MethodInterceptor {

  @Override
  public Object invoke(MethodInvocation joinPoint) throws Throwable {

    Method method = joinPoint.getMethod();
    String className = null;
    String methodName = null;
    Object[] args = joinPoint.getArguments();
    long start = System.currentTimeMillis();
    Object result = null;
    Object reqParams = null;
    try {
      methodName = method.getName();
      className = method.getDeclaringClass().getName();
      Parameter[] parameters = method.getParameters();
      reqParams = getRequestParams(args, parameters);
      result = joinPoint.proceed();
    } finally {
      long timeCost = System.currentTimeMillis() - start;
      Map<String, Object> map = new HashMap<>(8);
      map.put("method", className + "." + methodName);
      map.put("requestParams", reqParams);
      map.put("responseParams", result);
      map.put("timeCost", timeCost + "ms");
      log.info("LogAspect:{}", JsonUtils.toJsonString(map));
    }
    return result;
  }


  /**
     * 重构请求参数
     *
     * @param args       参数
     * @param parameters 参数名
     * @return 重构后的请求参数
     */
  public Object getRequestParams(Object[] args, Parameter[] parameters) {
    if (Objects.isNull(args)) {
      return null;
    }
    if (args.length == 1 && !(args[0] instanceof HttpServletRequest) && !(args[0] instanceof HttpServletResponse)) {
      return args[0];
    }

    List<Object> result = new ArrayList<>();
    try {
      for (int i = 0; i < args.length; i++) {
        Object param = args[i];
        if (param instanceof HttpServletRequest) {
          result.add("HttpServletRequest");
          continue;
        }
        if (param instanceof HttpServletResponse) {
          result.add("HttpServletResponse");
          continue;
        }
        Map<Object, Object> map = new HashMap<>(2);
        map.put(parameters[i].getName(), param);
        result.add(map);
      }
    } catch (Exception e) {
      log.warn("LogAspect getRequestParams error:{}", ExceptionUtils.getStackTrace(e));
    }
    return result;
  }

}

3、自定义 Advisor

将上面自定义的切点 pointcut 与通知 advice 整合,实现我们的切面

@Setter
public class CustomStatusAdvisor extends AbstractBeanFactoryPointcutAdvisor {

  private Pointcut customStatusPointcut;

  @Override
  public Pointcut getPointcut() {
    return customStatusPointcut;
  }
}

4、Bean 注入

@Configuration
public class CustomStatisPointConfig {

    @Bean
    public CustomStatusAdvisor init() {
        CustomStatusAdvisor customStatusAdvisor = new CustomStatusAdvisor();
        customStatusAdvisor.setCustomStatusPointcut(new CustomStatusPointcut());
        customStatusAdvisor.setAdvice(new CustomStatusAdvice());
        return customStatusAdvisor;
    }
}

ContactAuthor