AOP切入点
通过AOP提供的切入点表达式,我们除了能在类,方法等位置指定切入点,还能在注解位置加入切入点。这样在我们添加注解的位置就会执行切面方法。
自定义注解
1 2 3 4 5 6 7 8 9 10 11
| @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface SystemLog {
String actionType();
String actionDescription();
String functionName();
}
|
定义一个切入点
1 2 3
| @Pointcut(value = "@annotation(com.fizzy.core.annotation.SystemLog)") private void logPointcut() { }
|
定义一个切面方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| @Before("logPointcut()") private void beforeLog(JoinPoint joinPoint) throws ClassNotFoundException, NoSuchMethodException { SystemLog systemLog = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(SystemLog.class); String actionName = systemLog.actionDescription(); String actionType =systemLog.actionType(); String functionName = systemLog.functionName(); Map<String, Object> params = getFields(joinPoint); System.out.println(actionName); System.out.println(actionType); System.out.println(functionName); System.out.println(params); }
private static Map<String, Object> getFields(JoinPoint joinPoint) throws ClassNotFoundException, NoSuchMethodException { String classType = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes(); ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer(); String[] parameterNames = pnd.getParameterNames(Class.forName(classType).getMethod(methodName, parameterTypes)); Object[] args = joinPoint.getArgs(); HashMap<String, Object> paramMap = new HashMap(); for (int i = 0; i < Objects.requireNonNull(parameterNames).length; i++) { paramMap.put(parameterNames[i], args[i]); } return paramMap; }
|
切入的代码加上注解
1 2 3 4 5
| @GetMapping("/findById") @SystemLog(actionType = "query", actionDescription = "打开帖子详情", functionName = "postDetail") public Post postDetail(@RequestParam int id) { return postService.findPostById(id); }
|
结果