非注解切面实现
前言
Github:https://github.com/HealerJean
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;
}
}