2009-06-03 8 views
10

Ho la seguente configurazione XML:Come posso utilizzare la configurazione Spring XML per impostare una proprietà bean con l'elenco di tutti i bean di un certo tipo?

<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> 

I "compiti" contiene tutti i fagioli di tipo semplice. Il problema con questo è che potrei dimenticare di aggiungere un bean semplice che ho configurato alla lista.

ho potuto fare questo programatically utilizzando

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

e impostando il fagiolo lista con i fagioli recuperati.

C'è un modo per farlo utilizzando solo la configurazione XML?

risposta

8

il file di contesto dovrebbe in questo modo:

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

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

nota l'aggiunta autowire="byType" e the autowiring documentation.

+0

Questo non dovrebbe semplicemente mettere la lista stessa nella proprietà delle attività di Comp? In che modo questo aiuta a popolare la lista stessa con tutti i bean di tipo Simple? – rudolfson

+1

@rudolfson: la lista non dovrebbe più esistere e javadoc per @Autowired ha una bella spiegazione delle regole: http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/beans /factory/annotation/Autowired.html –

+0

Grazie per avermi illuminato. Non ho letto i documenti autowire fino alla fine e quindi non ero a conoscenza di questa capacità. +1 per la tua risposta! – rudolfson

3

Suggerirei di scrivere il proprio FactoryBean per creare un elenco di questo tipo. Questo sarebbe riutilizzabile e quindi configurabile usando solo XML. Il FactoryBean sarebbe simile

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; 
    } 
} 

Allora la vostra configurazione XML sarebbe

<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> 

NOTA: Non ho avuto il tempo per testare l'esempio di cui sopra. Ho appena usato il codice che avevo già come modello. ;) Soprattutto non sono sicuro se passare Simple come argomento Class per la proprietà type funziona in questo modo. Basta fare un tentativo. Nel peggiore dei casi dovresti usare String come tipo di proprietà e usare Class.forName(type) per ottenere la tua classe. Ma la mia ipotesi è che la primavera faccia questa trasformazione per te.

EDIT Anche se questa soluzione dovrebbe funzionare, raccomando la risposta di Robert Munteanu.

Problemi correlati