从带注释的字段接收注释值

时间:2017-05-22 12:03:08

标签: java spring reflection annotations runtime

是否可以在字段内接收注释值? 想象一下,我有这个界面:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

我有这样的实施:

class SomeClass {
    @MyAnnotation("Annotation")
    private MyClass myClass;
}

我想要理解的是:是否可以在MyClass中获得MyAnnotation的值?我想在类MyClass中实现一个方法,它将返回指定注释的值。因此,myClass.getAssignedAnnotationValue()将返回“注释”。 如果不可能,请通知我。

2 个答案:

答案 0 :(得分:1)

  

是否可以知道注释字段中的注释值

这是不可能的。

您可能有2个不同的班级

class SomeClass {
    @MyAnnotation("Annotation")
    private MyClass myClass;
    public SomeClass(MyClass myClass) {
        this.myClass=myClass;
    }
}

class SomeClassNo Annotation {
    private MyClass myClass;
    public SomeClassNo(MyClass myClass) {
        this.myClass=myClass;
    }
}

然后创建一个MyClass

的实例

MyClass instance = new MyClass();

然后是2个类实例 new SomeClass(instance)new SomeClassNo(instance)都引用了相同的instance。因此实例不知道是否注释了引用字段。

唯一可能的情况是将容器引用传递给MyClass

答案 1 :(得分:0)

没有直接的方法来实现你的要求。

解决方法:

限制:

  1. 此解决方法不会强制执行任何类型的编译时检查,完全由您负责处理。
  2. 这只适用于MyClass将成为一个春天豆。
  3. class MyClass {
        public String annotatedValue;
    }
    

    您可以通过以下方式编写Spring BeanPostProcessor。

    public class SampleBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
    
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
    
            Field[] fields = bean.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (field instanceof MyClass && field.isAnnotationPresent(MyAnnotation.class)) {
                    String value = field.getDeclaredAnnotation(MyAnnotation.class).value();
                    ((MyClass) field).annotatedValue = value;
                    return bean;
                }
            }
            return bean;
        }
    }
    

    在app启动期间,将为每个bean调用上面的BeanPostProcessor。它将检查给定bean的所有字段,以查看该字段是否为MyClass类型。如果是,它将从注释中提取值并将其设置在annotatedValue字段中。

    这种方法的问题是你可以在任何类的任何属性上使用MyAnnotation。 您无法强制注释仅在MyClass上使用。