2015-07-03 154 views
1

我正在創建一個自定義的註釋,它從特定時間間隔(min,max)設置隨機int數。無法通過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; 
} 

這裏是彈簧上下文XML配置:

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

然而,當我測試程序,所需的字段的值是0(選中的10倍) 。打印要注入的字段名稱和值的代碼行也不起作用。什麼可能是錯誤?如何正確定義字段自定義註釋?

使用該註釋

PS

類別:

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(); 
} 
+0

你的字段定義是什麼樣的,你的註釋是什麼樣的。 'getFields'只會讓你訪問給定類上的'public'字段。所以如果它是私人的,它不會檢索它。改爲使用'getDeclaredFields'。 –

+0

你有沒有試過在Field [] fields = bean.getClass()。getFields();「並查看返回的內容(或者該方法甚至可以運行)? –

+0

字段的數組是空的。 –

回答

2

代替getFields使用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; 
     } 
    });