Primavera: ¿Inyectando una clase interior privada como miembro de una clase exterior?
-
23-09-2019 - |
Pregunta
Tengo la siguiente estructura de clase
public class Outer{
private Mapper a;
....
private class MapperA implements Mapper {
}
private class MapperB implements Mapper {
}
}
En mi archivo de configuración de Spring, me gustaría crear un frijol externo y asignar uno de mappersa o mapperb como propiedad. es posible?
<bean id="outer" class="mypackage.Outer">
<property name="a" ?????='????' />
</bean>
Editar: algo más de información, según los comentarios de las respuestas:
Me puse perezoso con mi ejemplo anterior. Tengo un setter/getter público para la variable de instancia mapper.
La razón por la que todas las clases de mapeadores son clases internas es porque podría haber muchas de ellas, y solo se usarán en esta clase. Simplemente no quiero un montón de clases de Cruft en mi proyecto. Tal vez un método de fábrica es una mejor idea.
Solución
Normalmente necesitarías un setter para el Mapper
dentro de Outer
, y una instancia del requerido Mapper
. Pero como son:
- privado
- interno
clases, eso se vuelve un poco complicado (como has identificado). Si los hace públicos, estoy seguro de que podrías poner una instancia usando Outer$MapperA
etc. Pero eso parece un poco desagradable. Asi que:
- ¿Necesitan ser internos y privados?
- quizás el exterior puede tomar una cadena y determinar de eso si instanciar
MapperA
oMapperB
. es decir, hay alguna capacidad de fábrica aquí.
Lo más simple que debe hacer es determinar realmente si necesitan ser internos/privados. Si es así, entonces realmente no deberían referenciarse dentro de la configuración, lo que debería estar hablando de clases de acceso público.
Otros consejos
La primavera puede instanciarse private
clases internas. El problema real con su configuración es que tampoco sonstatic
, así que necesitas un <constructor-arg .../>
:
<bean id="outer" class="mypackage.Outer">
<property name = "a">
<bean class = "mypackage.Outer.MapperA">
<constructor-arg ref = "outer" />
</bean>
</property>
</bean>
Hasta donde yo sé, es imposible hasta que hagas MapperA
y MapperB
clases públicas habituales.
Pero si desea mantenerlos como clases privadas internas, puede "inyectarlas" manualmente.
Necesitará crear método con @PostInit
anotación e inicializa tu a
campo allí (a = new MapperA ()
por ejemplo, o algo más complejo). Con este enfoque, también debe verificar que las devoluciones de llamada de inicialización se activen en su configuración de resorte.