**
动态修改注解属性
**
注解的属性在Java程序中基本上是硬编码。
突然有一个修改注解属性的想法。此想发来源于最近业务重构中。具体业务如下。
最近在做Ar 服务boot时候,发现前大神写的相关摄像头业务,在不停的登录注册(SDK代码说明不明确的原因),偶尔出现当前用户不存在的情况。突发奇想,觉得可以用AOP拦截去登陆操作。但是注销用户需要用户登录完的userId.感觉可以用AOP @Before 切面方式在需要设备登录的地方做切面处理。
有此想法之后便开始在学习的代码库中做测试。疯狂的百度查阅资料。确实发现可以去修改这个属性,其中Aop 切点方法中关键的代码如下:
注解定义如下:
/**
* @Author:ccbobe
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface Count {
public String count() default "0";
}
关键代码块
/**
* 动态修改注解参数
*/
@Before(value = "@annotation(com.bobe.leader.core.Count)")
public void count(JoinPoint joinPoint){
//动态修改注解属性
Signature signature = joinPoint.getSignature();
// 类名
String targetName = joinPoint.getTarget().getClass().getName();
// 方法名
String methodName = joinPoint.getSignature().getName();
// 参数
Object[] arguments = joinPoint.getArgs();
// 切点类
Class targetClass = null;
try {
targetClass = Class.forName(targetName);
} catch (ClassNotFoundException e) {
}
Method[] methods = targetClass.getMethods();
Count count = null;
Method target = null;
//获取当前方法注解信息
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazz = method.getParameterTypes();
if (clazz.length == arguments.length) {
count = method.getAnnotation(Count.class);
target = method;
break;
}
}
}
//反射修改当前注解属性值
MethodSignature methodSignature = (MethodSignature) signature;
boolean b = target.isAnnotationPresent(Count.class);
if (b){
Count annotation = target.getAnnotation(Count.class);
InvocationHandler handler = Proxy.getInvocationHandler(annotation);
try {
Field memberValues = handler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map<Object, Object> map = (Map<Object, Object>) memberValues.get(handler);
map.put("count", new Random().nextInt());
} catch (NoSuchFieldException | IllegalAccessException e){
e.printStackTrace();
}
}
}
如需要看完整的代码可以去此处去下载。
旺哥git仓库地址