spring-annotation
基于spring的注解开发
类似python的装饰器可以实现一下功能
- 动态修改属性
- 动态新增功能(不侵入原代码)
- 动态改变执行逻辑
spring 配置略过
开发注解
1. 定义注解
1
2
3
4
5
6
7
({ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
(RetentionPolicy.RUNTIME)
public Patch {
String key() default "";
String value() default "";
}
2. 注解实现
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
/**
* @Author 杨帅
* @Date 2020/11/12 23:09
* @Version 1.0
*/
public class PatchAspect {
"Patch()") (
public void after(JoinPoint joinPoint) {
// 记录参数
}
"Patch()",returning="returnValue") (pointcut =
public void afterJoinPoint(JoinPoint joinPoint ,Object returnValue){
// 记录返回值
}
"@annotation(注解路径)") (
public void patch(){}
"Patch()") (
public void around(ProceedingJoinPoint joinPoint){
try {
StopWatch sw = new StopWatch();
sw.start();
//获取方法参数
Object[] args = joinPoint.getArgs();
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = sign.getParameterNames();
System.out.println("parameter list: ");
for (int i = 0; i < parameterNames.length; i++) {
System.out.println(parameterNames[i] + " = " + args[i]);
// 这里可以通过参数名配合注解的值直接修改对应的参数 做拦截操作或者参数校验
}
//获取注解参数
Patch annotation = sign.getMethod().getAnnotation(Patch.class);
System.out.println("value = " + annotation.value());
System.out.println("key = " + annotation.key());
/*
// 这里可以不知道注解的情况下获取注解
Annotation[][] annotations;
try {
annotations = pjp.getTarget().getClass().
getMethod(methodName, parameterTypes).getParameterAnnotations();
} catch (Exception e) {
throw new SoftException(e);
}
*/
//执行方法
joinPoint.proceed();
//方法执行后逻辑
sw.stop(args);
System.out.println(sw.prettyPrint());
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
总结
注解本质意义上就是代码的注释,如果没有实现解析的逻辑那么仅仅是注释。
对于注释有两种方式,一种是编译直接扫描,一种是运行时反射。
注意:基于 java 注解的开发不同于动态语言的简单逻辑,很多时候需要在代码中有效的处理各种类型的判断以及各种未知