Pergunta

Existe uma maneira na Primavera que eu posso auto preencher uma lista com todos os grãos de tipo e qualquer de seus subtipos? Eu tenho um método setter que se parece com:

setMyProp(List<MyType> list)

E eu gostaria de autowire em qualquer feijão de MyType e todas as subclasses de MyType.

Obrigado, Jeff

Foi útil?

Solução

Sim, você pode fazer isso. Os docs primavera dizer:

Também é possível fornecer todas feijões de um tipo particular da ApplicationContext adicionando o anotação para um campo ou método que espera uma matriz desse tipo.

Note que ele diz que você precisa esperar um array, não uma lista. Isso faz sentido, porque o tipo genérico apagamento significa uma lista pode não funcionar em tempo de execução. No entanto, tome o seguinte teste de unidade, que funciona:

<?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 este teste de unidade:

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

}

Assim, oficialmente, você deveria autowire TypeA[], não List<TypeA>, mas a lista de boas obras.

Outras dicas

Se for aceitável para preencher a lista de seu código do aplicativo e não de dentro do arquivo de definição de feijão você poderia usar o org.springframework.beans.factory.xml.XmlBeanFactory e pedir-lhe "getBeansOfType( MyType.class )". Isto dá-lhe todos os grãos do tipo (e subtipo) de MyType.

Se você pode usar @Autowired dentro do código a ser povoada você pode usar com segurança o caminho mencionado por skaffman. Se você insistir em configuração XML, há uma pequena biblioteca chamada Hera para alcançar este objectivo. Esentially configuração de um cenário descrito por você se parece com isso:

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

Este vai injetar todos os grãos de nível superior Primavera execução SuperType como List no bean cliente.

resposta curta: Não.

Resposta longa: trabalho Java genéricos por tipo apagamento, o que significa que em tempo de execução que o parâmetro é simplesmente uma lista, e não uma lista de um tipo genérico. Como tal, você não pode descobrir o que está destinado a ser de tipo de parâmetro MyType por isso não seria possível implementar esse comportamento.

Dito isto, existem formas alternativas de fazer isso. A mais óbvia parece ser a ouvir para a criação de feijão e depois ver se eles são de MyType (ou subclasses) e, em seguida, mantendo uma referência.

Há provavelmente algumas maneiras de fazer isso. Um deles é criação de um feijão de pós-processador . Desta forma, você vai ser notificado de cada grão que é criado.

Devido ao código legado e desaparecidos @Autowired eu resolvê-lo como:

MyBean implements ApplicationContextAware{

  @Override
  public void setApplicationContext(ApplicationContext ctx) throws BeansException {
    final Map<String, HttpRequestHandlerTemplate> beansOfType = ctx.getBeansOfType(RequiredBean.class);
    ...
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top