fagioli Lista Primavera per tipo
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
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);
...
}