2012-02-19 8 views
19

Podczas korzystania ze sprężyny, czy można ustawić właściwość tylko wtedy, gdy przekazana wartość nie jest pusta?Sprężyna - ustaw właściwość tylko wtedy, gdy jej wartość nie jest pusta

Przykład:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param}"/> 
</bean> 

Zachowanie szukam jest:

some.Type myBean = new some.Type(); 
if (${some.param} != null) myBean.setAbc(${some.param}); 

Powodem muszę to od abc ma wartość domyślną, która nie chce, aby zastąpić z a null. A Groszek, który tworzę, nie znajduje się pod moją kontrolą źródła - więc nie mogę zmienić jego zachowania. (Również abc do tego celu może być prymitywne, więc nie mogę ustawić go z zerem i tak

EDIT:.
Według odpowiedzi Myślę, że moje pytanie wymaga wyjaśnienia

ja. Mam komponent bean, który muszę utworzyć i przekazać do 3rd party, którego używam.Ten komponent ma wiele właściwości (12 obecnie) różnych typów (int, boolean, String, itp.)
Każda właściwość ma wartość domyślną - nie wiem co to jest i wolałaby nie wiedzieć, chyba że stanie się problemem. To, czego szukam, to ogólne rozwiązanie, które pochodzi ze zdolności Springa - obecnie jedynym rozwiązaniem, jakie mam, jest refleksja.

Konfiguracja

<bean id="myBean" class="some.TypeWrapper"> 
    <property name="properties"> 
    <map> 
     <entry key="abc" value="${some.value}"/> 
     <entry key="xyz" value="${some.other.value}"/> 
     ... 
     </map> 
    </property> 
</bean> 

Kod

public class TypeWrapper 
{ 
    private Type innerBean; 

    public TypeWrapper() 
    { 
     this.innerBean = new Type(); 
    } 

    public void setProperties(Map<String,String> properties) 
    { 
     if (properties != null) 
     { 
      for (Entry<String, Object> entry : properties.entrySet()) 
      { 
       String propertyName = entry.getKey(); 
       Object propertyValue = entry.getValue(); 

       setValue(propertyName, propertyValue); 
      } 
     } 
    } 

    private void setValue(String propertyName, Object propertyValue) 
    { 
     if (propertyValue != null) 
     { 
      Method method = getSetter(propertyName); 
      Object value = convertToValue(propertyValue, method.getParameterTypes()[0]); 
      method.invoke(innerBean, value); 
     } 
    } 

    private Method getSetter(String propertyName) 
    { 
     // Assume a valid bean, add a "set" at the beginning and toUpper the 1st character. 
     // Scan the list of methods for a method with the same name, assume it is a "valid setter" (i.e. single argument) 
     ... 
    } 

    private Object convertToValue(String valueAsString, Class type) 
    { 
     // Check the type for all supported types and convert accordingly 
     if (type.equals(Integer.TYPE)) 
     { 
      ... 
     } 
     else if (type.equals(Integer.TYPE)) 
     { 
      ... 
     } 
     ... 
    } 
} 

Prawdziwy "trudności" jest w trakcie realizacji convertToValue dla wszystkich możliwych typów wartości. Zrobiłem to więcej niż jeden raz w życiu - więc nie jest to poważny problem, aby go wdrożyć dla wszystkich możliwych rodzajów, których potrzebuję (głównie prymitywów i kilku enum) - ale miałem nadzieję, że istnieje bardziej inteligentne rozwiązanie.

Odpowiedz

1

Można utworzyć klasy narzędzie, które będzie działać jako klasa fabrycznym dla some.Type i owinąć logiki tam

na przykład:

public class TypeFactory { 
    public static Type craeteType(SomeType param){ 
     Type t = new Type(); 
     if(param!=null) 
      t.setParam(param); 
    } 
} 

i na XML skonfigurować tworzenie fasoli przy użyciu tej metody fabryki

<bean id="myBean" class="some.Type" 
     factory-method="craeteType"> 
    <constructor-arg ref="param"/> 
</bean> 
3

można użyć domyślnej wartości koncepcję własności Configurer w Spring Framework, jak następuje:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param : your-default-value}"/> 
</bean> 

można ustawić wartość domyślną według tego podejścia. W tym kontekście konfiguracja, jeśli istnieje klucz some.param, więc jego wartość ustawiona jest w właściwości abc, a jeśli nie istnieje, your-default-value ustawiona w właściwości abc.

Uwaga: Kolejną zaletą tej metody jest: "W modelu programowania POJO lepsze approzh jest członkiem klasy, nie ma wartości domyślnej, a wartość domyślna jest wstrzykiwana z poza klasy."

+0

Dzięki za cynk - może to być pomocna w przyszłości, ale w moim przypadku nie mogę jej użyć - jak już wspomniałem, ten komponent bean nie znajduje się w mojej źródłowej kontroli - więc nie wiem, jaki jest jego domyślny (i nie chcę wiedzieć). Miałem nadzieję na coś z linii: '' – RonK

5

Aby rozwiązać problem, trzeba użyć SEL .. (wiosna Expression Language) Dzięki tej funkcji (dodanej w Spring 3.0) można taki jak inny dynamiczny język pisania Warunkiem context, odpowiedź brzmi:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="#(if(${some.param} != null) ${some.param})"/> 
</bean> 

uzyskać więcej informacji, patrz (ten tutorial co mówi użyj SEL w pliku kontekstowym): http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html

+6

Czy to jeszcze nie zda pusty ciąg, jeśli parametr ma wartość zerową? OP nie chce niczego przekazać: chce uniknąć wywoływania setera. –

+0

'# {$ {some.param}! = #null? $ {some.param}: #null} wydaje się być bardziej poprawne. – Vadzim

0

Mam to działa z następującym fragmencie:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="#{'${some.param}'=='' ? null : '${some.param}'}" /> 
</bean> 
+0

Nie to, czego potrzebowałem - ale dzięki to. – RonK

+0

@Ronk - czy znalazłeś rozwiązanie, aby to zrobić? Muszę to zrobić i nie mogę znaleźć rozwiązania. – dharag

+0

@dharag - W końcu zaimplementowałem własne rozwiązanie oparte na refleksach, używając FactoryBean do stworzenia obiektów, które chciałem. Nie znalazłem wbudowanego rozwiązania. – RonK

27

Można użyć SpEL i zastępczy i domyślną wartość dla mechanizmów zastępczych razem w następujący sposób:

<bean name="myBean" class="some.Type"> 
    <property name="abc" value="${some.param:#{null}}"/> 
</bean> 
+0

Już odpowiedziałeś na to pytanie raz :) (a także trochę inaczej) – RonK

+1

Och, tak, ale nowsza odpowiedź jest prostsza :) – MJM

+0

To zdecydowanie najlepsze rozwiązanie we wszystkich odpowiedziach, thanks1 –

Powiązane problemy