2013-10-22 32 views
2

我使用BeanUtils.setProperty來設置bean的深層屬性。設置bean的深層屬性,如果需要的話創建中間實例

Home home = new Home() ; 
String path = "home.family.father.age"; 
Integer value = 40; 

BeanUtils.setProperty(home, path, value); 
// Does the same as home.getHome().getFamily().getFather().setAge(value); 
// But stops on null (instead of throwing an NPE). 

的BeanUtils的行爲是什麼也不做,如果中介屬性之一是null。例如在我的情況下,homefamily屬性是null,沒有任何反應。如果我做

family = new Family(); 

然後father將是無效和我必須得初始化。很顯然,我的真實用例更復雜,具有許多動態屬性(還有索引的)。

有沒有辦法告訴BeanUtils實例化中間成員?我知道一般情況下這是不可能的(因爲財產的具體類型可能不知道)。但在我的情況下,所有的屬性都有具體的類型,並且是合適的bean(使用公共無參數構造函數)。所以這是可能的。

我想確保在滾動我自己之前還沒有現有的解決方案(使用BeanUtils或其他)。

回答

1

我推出了自己的。它只支持簡單的屬性,但我想添加對嵌套/映射屬性的支持不會太難。

這裏是任何人的情況下一個要點需要同樣的事情: https://gist.github.com/ThomasGirard/7115693

而這裏的最重要的部分是什麼樣子:

/** Mostly copy-pasted from {@link PropertyUtilsBean.setProperty}. */ 
public void initProperty(Object bean, String path) throws SecurityException, NoSuchMethodException, 
     IllegalAccessException, InvocationTargetException { 

    // [...] 

    // If the component is null, initialize it 
    if (nestedBean == null) { 

     // There has to be a method get* matching this path segment 
     String methodName = "get" + StringUtils.capitalize(next); 
     Method m = bean.getClass().getMethod(methodName); 

     // The return type of this method is the object type we need to init. 
     Class<?> propType = m.getReturnType(); 
     try { 
      // Since it's a bean it must have a no-arg public constructor 
      Object newInst = propType.newInstance(); 
      PropertyUtils.setProperty(bean, next, newInst); 
      // Now we have something instead of null 
      nestedBean = newInst; 
     } catch (Exception e) { 
      throw new NestedNullException("Could not init property value for '" + path + "' on bean class '" 
        + bean.getClass() + "'. Class: " + propType); 
     } 
    } 

    // [...] 

} 
相關問題