无法通过 ReflectionUtils.setField 设置字段值
Unable to set field value via ReflectionUtils.setField
我正在创建一个自定义注释,它根据特定间隔(最小值、最大值)设置随机整数。
@GenerateRandomInt(min=2, max=7)
我已经实现了接口BeanPostProcessor
。这是它的实现:
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;
}
这是 spring 上下文 xml 配置:
<bean class="InjectRandomIntAnnotationBeanPostProcessor"/>
<bean class="Quotes" id="my_quote">
<property name="quote" value="Hello!"/>
</bean>
但是,当我测试程序时,所需字段的值为0(检查10次)。打印要注入的字段名称和值的代码行也不起作用。可能是什么错误?如何正确定义字段自定义注释?
PS
使用此注释的 Class:
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");
}
}
}
描述注解@GenerateRandomInt的接口
@Retention(RetentionPolicy.RUNTIME)
public @interface GenerateRandomInt {
int min();
int max();
}
而不是 getFields
use getDeclaredFields
。
第一个只会给你 public
字段,后者会给你所有字段。
另一个提示:
由于您已经在使用 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;
}
});
我正在创建一个自定义注释,它根据特定间隔(最小值、最大值)设置随机整数。
@GenerateRandomInt(min=2, max=7)
我已经实现了接口BeanPostProcessor
。这是它的实现:
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;
}
这是 spring 上下文 xml 配置:
<bean class="InjectRandomIntAnnotationBeanPostProcessor"/>
<bean class="Quotes" id="my_quote">
<property name="quote" value="Hello!"/>
</bean>
但是,当我测试程序时,所需字段的值为0(检查10次)。打印要注入的字段名称和值的代码行也不起作用。可能是什么错误?如何正确定义字段自定义注释?
PS
使用此注释的Class:
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");
}
}
}
描述注解@GenerateRandomInt的接口
@Retention(RetentionPolicy.RUNTIME)
public @interface GenerateRandomInt {
int min();
int max();
}
而不是 getFields
use getDeclaredFields
。
第一个只会给你 public
字段,后者会给你所有字段。
另一个提示:
由于您已经在使用 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;
}
});