2009-06-03 12 views
10

mam następującą konfigurację XML:Jak używać konfiguracji Spring XML do ustawiania właściwości komponentu bean z listą wszystkich fasoli określonego typu?

<bean id="bean1" class="Simple"/> 
<bean id="bean2" class="Simple"/> 

<bean id="tasks" class="java.util.ArrayList"> 
    <constructor-arg> 
     <list> 
      <ref bean="bean1" /> 
      <ref bean="bean2" />     
     </list> 
    </constructor-arg> 
</bean> 

<bean id="list" class="Comp"> 
    <property name="tasks" ref="tasks"/> 
</bean> 

„Zadania” zawiera wszystkie ziarna typu proste. Problem polega na tym, że mogę zapomnieć o dodaniu prostego komponentu, który skonfigurowałem do listy.

mogę to zrobić programowo za pomocą

Map map = context.getBeansOfType(Simple.class); 

i ustawienie listy Bean z ziaren odzyskać.

Czy jest jakikolwiek sposób na to, używając tylko konfiguracji XML?

Odpowiedz

8

Plik kontekst powinien słuszne:

<bean id="bean1" class="Simple"/> 
<bean id="bean2" class="Simple"/> 

<bean id="list" class="Comp" autowire="byType"/> 

Uwaga dodanie autowire="byType" i the autowiring documentation.

+0

Czy to nie wystarczy umieścić samą listę w właściwości zadań Comp? W jaki sposób pomaga to w zapełnianiu listy wszystkimi ziarnami typu Simple? – rudolfson

+1

@rudolfson: lista nie powinna już istnieć, a javadoc dla @Autowired ma ładne wyjaśnienie zasad: http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans /factory/annotation/Autowired.html –

+0

Dzięki za oświecenie mnie. Nie czytałem dokumentacji z autowire do końca, więc nie wiedziałem o tej możliwości. +1 za odpowiedź! – rudolfson

3

Proponuję napisać własną FactoryBean do tworzenia takiej listy. To byłoby wielokrotnego użytku, a następnie konfigurowalne tylko za pomocą XML. FactoryBean wyglądałby

import java.util.ArrayList; 
import java.util.List; 

import org.springframework.beans.factory.FactoryBean; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.util.Assert; 

public class CollectingListFactoryBean implements FactoryBean, ApplicationContextAware { 
    private ApplicationContext appCtx; 
    private Class type; 

    public Object getObject() { 
     Assert.notNull(type, "type must be initialized"); 
     List result = new ArrayList(); 
     result.addAll(appCtx.getBeansOfType(type).values()); 
     return result; 
    } 

    public Class getObjectType() { 
     return List.class; 
    } 

    public boolean isSingleton() { 
     return false; 
    } 

    public void setApplicationContext(ApplicationContext applicationContext) { 
     this.appCtx = applicationContext; 
    } 

    public void setType(Class type) { 
     this.type = type; 
    } 
} 

Następnie konfiguracja XML byłoby

<bean id="bean1" class="Simple"/> 
<bean id="bean2" class="Simple"/> 

<bean id="tasks" class="CollectingListFactoryBean"> 
    <property name="type" value="Simple" /> 
</bean> 

<bean id="list" class="Comp"> 
    <property name="tasks" ref="tasks"/> 
</bean> 

UWAGA: Nie miałem czasu, aby przetestować przykład powyżej. Po prostu użyłem kodu, który już miałem jako szablon. ;) Szczególnie nie jestem pewien, czy przekazanie Simple jako argumentu Class dla właściwości type działa w ten sposób. Po prostu daj temu szansę. W najgorszym przypadku musisz użyć String jako typu nieruchomości i użyć Class.forName(type), aby uzyskać swoją klasę. Ale domyślam się, że Spring dokonuje tej transformacji dla ciebie.

EDIT Mimo że to rozwiązanie powinno zadziałać, proponuję odpowiedź Roberta Munteanu.

Powiązane problemy