Primavera: Injetando uma classe interna privada como membro de uma classe externa?
-
23-09-2019 - |
Pergunta
Eu tenho a seguinte estrutura de classe
public class Outer{
private Mapper a;
....
private class MapperA implements Mapper {
}
private class MapperB implements Mapper {
}
}
No meu arquivo de configuração de primavera, gostaria de criar um feijão externo e atribuir um de Mappera ou Mapperb como uma propriedade. Isso é possível?
<bean id="outer" class="mypackage.Outer">
<property name="a" ?????='????' />
</bean>
EDIT: Mais algumas informações, com base no feedback das respostas:
Fiquei preguiçoso com meu exemplo acima. Eu tenho um setter/getter público para a variável de instância do mapeador.
A razão pela qual todas as classes de mapeador são classes internas é porque poderia haver muitas delas, e elas só serão usadas nesta classe. Só não quero uma tonelada de aulas de Cruft no meu projeto. Talvez um método de fábrica seja uma ideia melhor.
Solução
Normalmente você precisaria de um setter para o Mapper
dentro de Outer
, e uma instância do necessário Mapper
. Mas como estes são:
- privado
- interno
Aulas, isso se torna um pouco complicado (como você identificou). Se você os tornar públicos, tenho certeza que você pode criar uma instância usando Outer$MapperA
etc. Mas isso parece um pouco desagradável. Então:
- Eles precisam ser internos e privados?
- Talvez Exterter possa pegar uma corda e determinar a partir de que instancie
MapperA
ouMapperB
. Ou seja, há algum recurso de fábrica aqui.
A coisa mais simples a fazer é realmente determinar se eles precisam ser internos/privados. Nesse caso, eles realmente não devem ser referenciados na configuração, que deve estar falando sobre classes acessíveis ao público.
Outras dicas
A primavera pode instanciar private
Classes internas. O problema real com sua configuração é que eles também não sãostatic
, então você precisa de um <constructor-arg .../>
:
<bean id="outer" class="mypackage.Outer">
<property name = "a">
<bean class = "mypackage.Outer.MapperA">
<constructor-arg ref = "outer" />
</bean>
</property>
</bean>
Tanto quanto eu sei, é impossível até você fazer MapperA
e MapperB
Classes públicas usuais.
Mas se você quiser mantê -los como aulas privadas internas, poderá "injetar" manualmente.
Você precisará criar método com @PostInit
anotar e inicializar seu a
campo lá (a = new MapperA ()
por exemplo, ou algo mais complexo). Com essa abordagem, você também deve verificar se os retornos de chamada de inicialização estão ligados na sua configuração de primavera.