我想提供注释与一些方法生成的一些值.
到目前为止我试过这个:
public @interface MyInterface {
String aString();
}
Run Code Online (Sandbox Code Playgroud)
@MyInterface(aString = MyClass.GENERIC_GENERATED_NAME)
public class MyClass {
static final String GENERIC_GENERATED_NAME = MyClass.generateName(MyClass.class);
public static final String generateName(final Class<?> c) {
return c.getClass().getName();
}
}
Run Code Online (Sandbox Code Playgroud)
思想GENERIC_GENERATED_NAME是static final,它抱怨说
注释属性的值
MyInterface.aString必须是常量表达式
那么如何实现呢?
Tim*_*ote 20
无法动态生成注释中使用的字符串.编译器RetentionPolicy.RUNTIME在编译时评估注释的注释元数据,但GENERIC_GENERATED_NAME直到运行时才知道.并且您不能将生成的值用于注释,RetentionPolicy.SOURCE因为它们在编译时被丢弃,因此这些生成的值永远不会被知道.
解决方案是使用带注释的方法.调用该方法(使用反射)来获取动态值.
从用户的角度来看,我们有:
@MyInterface
public class MyClass {
@MyName
public String generateName() {
return MyClass.class.getName();
}
}
Run Code Online (Sandbox Code Playgroud)
注释本身将被定义为
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface @MyName {
}
Run Code Online (Sandbox Code Playgroud)
实现这两个注释的查找非常简单.
// as looked up by @MyInterface
Class<?> clazz;
Method[] methods = clazz.getDeclaredMethods();
if (methods.length != 1) {
// error
}
Method method = methods[0];
if (!method.isAnnotationPresent(MyName.class)) {
// error as well
}
// This works if the class has a public empty constructor
// (otherwise, get constructor & use setAccessible(true))
Object instance = clazz.newInstance();
// the dynamic value is here:
String name = (String) method.invoke(instance);
Run Code Online (Sandbox Code Playgroud)
没有办法像其他人所说的那样动态修改注释的属性。尽管如此,如果你想实现这一点,有两种方法可以做到这一点。
将表达式分配给注释中的属性,并在检索注释时处理该表达式。在您的情况下,您的注释可以是
@MyInterface(aString = "objectA.doSomething(args1, args2)")
当您阅读该内容时,您可以处理该字符串并进行方法调用并检索该值。Spring 通过 SPEL(Spring 表达式语言)做到这一点。这是资源密集型的,每次我们要处理表达式时都会浪费 CPU 周期。如果您使用的是 spring,您可以挂钩 beanPostProcessor 并处理一次表达式并将结果存储在某处。(全局属性对象或可以在任何地方检索的地图中)。
jdk 存储注解映射的方式依赖于 Java 版本并且不可靠,因为它没有公开使用(它是私有的)。
您可以在此处找到参考实现。
https://rationaleemotions.wordpress.com/2016/05/27/changed-annotation-values-at-runtime/
PS:第二种方法我没试过。
| 归档时间: |
|
| 查看次数: |
29978 次 |
| 最近记录: |