简体   繁体   English

无法通过ReflectionUtils.setField设置字段值

[英]Unable to set field value via ReflectionUtils.setField

I am creating a custom made annotation that sets random int number from the specific interval (min, max). 我正在创建一个自定义注释,该注释从特定间隔(最小,最大)设置随机整数值。

 @GenerateRandomInt(min=2, max=7)

I have implemented interface BeanPostProcessor . 我已经实现了BeanPostProcessor接口。 Here is its implementation: 这是它的实现:

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

    Field[] fields=bean.getClass().getFields();
    for (Field field : fields) {
        GenerateRandomInt annotation = field.getAnnotation(GenerateRandomInt.class);

        System.out.println(field.getName());
        if(annotation!=null){


            int min = annotation.min();
            int max = annotation.max();

            Random random = new Random();

            int i = random.nextInt(max-min);
            field.setAccessible(true);
            System.out.println("Field name: "+field.getName()+" value to inject:"+i);
            ReflectionUtils.setField(field,bean,i);
        }
    }

    return bean;
}

Here is the spring context xml config: 这是spring上下文xml配置:

<bean class="InjectRandomIntAnnotationBeanPostProcessor"/>
<bean class="Quotes" id="my_quote">
    <property name="quote" value="Hello!"/>
</bean>

However, when I test the program, the value of the desired field is to the 0 (checked 10 times). 但是,当我测试程序时,所需字段的值将为0(检查10次)。 The code line, that prints the field name and value to be injected doesn't work as well. 打印行名称和要注入的值的代码行也不起作用。 What might be an error? 可能是什么错误? How is it possible to proper define the field custom made annotation? 如何正确定义字段定制注释?

PS PS

Class that uses this annotation: 使用此注释的类:

public class Quotes implements Quoter {

    @GenerateRandomInt(min=2, max=7)
    private int timesToSayHello;

    private String quote;
    public String getQuote() {
        return quote;
    }

    public void setQuote(String quote) {
        this.quote = quote;
    }

    @Override
    public void sayHello() {
        System.out.println(timesToSayHello);
        for (int i=0;i<timesToSayHello;i++) {
            System.out.println("Hello");
        }
    }
}

Interface that describes annotation @GenerateRandomInt 描述注解@GenerateRandomInt的接口

@Retention(RetentionPolicy.RUNTIME)
public @interface GenerateRandomInt {
    int min();
    int max();
}

Instead of getFields use getDeclaredFields . 代替getFields使用getDeclaredFields

The first will only give you public fields, the latter gives you all fields. 前者只给您public领域,后者给您所有领域。

Another tip: As you are already using ReflectionUtils I suggest using the doWithFields method to simplify your code. 另一个技巧:由于您已经在使用ReflectionUtils我建议使用doWithFields方法来简化您的代码。

ReflectionUtils.doWithFields(bean.getClass(), 
    new FieldCallback() {
        public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
            GenerateRandomInt annotation = field.getAnnotation(GenerateRandomInt.class);
            int min = annotation.min();
            int max = annotation.max();
            int i = random.nextInt(max-min);
            ReflectionUtils.makeAccessible(field);
            ReflectionUtils.setField(bean, field, i);
        }

    }, 
    new FieldFilter() {
        public boolean matches(Field field) {
            return field.getAnnotation(GenerateRandomInt.class) != null;
        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM