Java 动态修改注解值
有的场景需要动态修改注解中的属性值。 可以使用反射或者是spring EL 表达式。
定义注解
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInfo {
int order();
int size() default -1;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 反射
动态修改data字段上FieldInfo注解中的size属性值。利用Java的“反射”实现在程序中根据业务进行动态的修改。
Field sample = UploadImageRequest.class.getDeclaredField("data");
FieldInfo annotation = sample.getAnnotation(FieldInfo.class);
InvocationHandler handler = Proxy.getInvocationHandler(annotation);
Field field = handler.getClass().getDeclaredField("memberValues");
field.setAccessible(true);
Map map = (Map) field.get(handler);
//报文长度
int packetLength = in.getUnsignedShortLE(2);
map.put("size",10);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
这样size属性值就修改了。
# spring EL
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface RedisLock {
String value();
String param() default "";
long waitTime() default 30L;
long leaseTime() default 100L;
TimeUnit timeUnit() default TimeUnit.SECONDS;
LockType type() default LockType.FAIR;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RedisLock(value = "key",param = "#query.id",leaseTime = 30L)
public Vo update(Query query) {
}
1
2
3
2
3
@Around("@annotation(redisLock)")
public Object aroundRedisLock(ProceedingJoinPoint point, RedisLock redisLock) {
String lockName = redisLock.value();
Assert.hasText(lockName, "@RedisLock value must have length; it must not be null or empty");
String lockParam = redisLock.param();
String lockKey;
if (StringUtil.isNotBlank(lockParam)) {
String evalAsText = this.evalLockParam(point, lockParam);
lockKey = lockName + ':' + evalAsText;
} else {
lockKey = lockName;
}
}
private static final BladeExpressionEvaluator EVALUATOR = new BladeExpressionEvaluator();
private String evalLockParam(ProceedingJoinPoint point, String lockParam) {
MethodSignature ms = (MethodSignature)point.getSignature();
Method method = ms.getMethod();
Object[] args = point.getArgs();
Object target = point.getTarget();
Class<?> targetClass = target.getClass();
EvaluationContext context = EVALUATOR.createContext(method, args, target, targetClass, this.applicationContext);
AnnotatedElementKey elementKey = new AnnotatedElementKey(method, targetClass);
return EVALUATOR.evalAsText(lockParam, elementKey, context);
}
@Nullable
public String evalAsText(String expression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
return (String)this.eval(expression, methodKey, evalContext, String.class);
}
@Nullable
public <T> T eval(String expression, AnnotatedElementKey methodKey, EvaluationContext evalContext, @Nullable Class<T> valueType) {
return this.getExpression(this.expressionCache, methodKey, expression).getValue(evalContext, valueType);
}
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
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
上次更新: 2024/03/13, 15:24:21