Domanda

C'è un modo in primavera che posso automaticamente compilare un elenco con tutti i fagioli di un tipo e qualsiasi dei suoi sottotipi? Ho un metodo setter che assomiglia a:

setMyProp(List<MyType> list)

E vorrei autowire in qualsiasi fagioli di MyType e tutte le sottoclassi di MyType.

Grazie, Jeff

È stato utile?

Soluzione

Yup, si può fare questo. La documentazione di primavera dicono:

  

E 'anche possibile fornire tutte le   fagioli di un tipo particolare dalla   ApplicationContext aggiungendo il   annotazione un campo o un metodo che   aspetta un array di quel tipo.

Si noti che dice che è necessario aspettare un array, non una lista. Questo ha senso, perché la cancellazione di tipo generico: un elenco non può funzionare in fase di esecuzione. Tuttavia, prendere il seguente test di unità, che funziona:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">  

    <bean class="test.Test.TypeB"/>
    <bean class="test.Test.TypeC"/>
    <bean class="test.Test.TypeD"/>
</beans>

e questo unit test:

package test;

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {

    private @Autowired List<TypeA> beans;

    @org.junit.Test
    public void test() {
        assertNotNull(beans);
        assertEquals(2, beans.size());
        for (TypeA bean : beans) {
            assertTrue(bean instanceof TypeA);
        }
    }       

    public static interface TypeA {}
    public static class TypeB implements TypeA {}
    public static class TypeC extends TypeB {}
    public static class TypeD {}

}

Quindi ufficialmente, si suppone di autowire TypeA[], non List<TypeA>, ma l'elenco funziona bene.

Altri suggerimenti

Se è accettabile per riempire la lista dal codice dell'applicazione e non dall'interno del file di definizione di fagioli è possibile utilizzare la org.springframework.beans.factory.xml.XmlBeanFactory e chiedere che "getBeansOfType( MyType.class )". Questo ti dà tutti i fagioli di tipo (e il sottotipo) di MyType.

Se è possibile utilizzare @Autowired all'interno del codice per essere popolato è possibile utilizzare in modo sicuro il modo in cui parla skaffman. Se ti ostini a configurazione XML c'è una piccola libreria chiamata Hera per raggiungere questo obiettivo. Configurazione esentially di uno scenario descritto da voi assomiglia a questo:

<bean id="client" class="..">
    <property name="injectDynamicListHere">
        <hera:list class="my.custom.SuperType" />
    </property>
</bean>

Questo iniettare tutti i fagioli di livello superiore di primavera di attuazione SuperType come List nel chicco cliente.

Risposta breve:. No

Risposta lunga: generici Java funzionano per tipologia di cancellazione, il che significa che in fase di esecuzione che il parametro è semplicemente una lista, non un elenco di un tipo generico. In quanto tale, non si riesce a capire che è destinata ad essere di tipo di parametro MyType in modo che non sarebbe possibile implementare questo comportamento.

Detto questo, ci sono modi alternativi di fare questo. La più ovvia sembra essere di ascoltare per la creazione di fagioli e poi vedere se sono di MyType (o sottoclassi) e poi mantenere un riferimento.

C'è probabilmente un paio di modi per farlo. Uno è creando un bean post-processore . In questo modo si otterrà notifica di ogni chicco che viene creato.

A causa di codice legacy e dispersi @Autowired ho risolto piace:

MyBean implements ApplicationContextAware{

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class);
    ...
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top