Весна: инъекция частного внутреннего класса в качестве участника внешнего класса?
-
23-09-2019 - |
Вопрос
У меня есть следующая структура класса
public class Outer{
private Mapper a;
....
private class MapperA implements Mapper {
}
private class MapperB implements Mapper {
}
}
В моем весеннем файле конфигурации я хотел бы создать внешнюю фасоль и назначить одну из Mappera или Mapperb в качестве свойства. Это возможно?
<bean id="outer" class="mypackage.Outer">
<property name="a" ?????='????' />
</bean>
РЕДАКТИРОВАТЬ: дополнительная информация, основанная на отзывах ответов:
Я ленился с моим примером. У меня есть общедоступный сеттер/getter для переменной экземпляра Mapper.
Причина, по которой все классы Mapper являются внутренними классами, заключается в том, что их потенциально может быть много из них, и они будут использоваться только в этом классе. Я просто не хочу кучу классов Cruft в моем проекте. Может быть, фабричный метод - лучшая идея.
Решение
Обычно вам нужен сеттер для Mapper
в пределах Outer
, и экземпляр необходимого Mapper
. Анкет Но как это:
- частный
- внутренний
Занятия, это становится немного сложным (как вы идентифицировали). Если вы сделаете их публичными, я уверен, что вы сможете создать экземпляр, используя Outer$MapperA
и т. д. Но это кажется немного противным. Так:
- Должны ли они быть внутренним и частным?
- Возможно, внешний может взять строку и определить из этого, создать ли экземпляры
MapperA
или жеMapperB
. Анкет т.е. здесь есть некоторые заводские возможности.
Самое простое, что нужно сделать, это действительно определить, должны ли они быть внутренним/частным. Если это так, то на них действительно не следует ссылаться в конфигурации, которые должны говорить об общедоступных классах.
Другие советы
Весна может создать экземпляр private
Внутренние классы. Фактическая проблема с вашей конфигурацией заключается в том, что они также не являютсяstatic
, так что вам нужен <constructor-arg .../>
:
<bean id="outer" class="mypackage.Outer">
<property name = "a">
<bean class = "mypackage.Outer.MapperA">
<constructor-arg ref = "outer" />
</bean>
</property>
</bean>
Насколько я знаю, это невозможно, пока вы не сделаете MapperA
а также MapperB
обычные общественные занятия.
Но если вы действительно хотите держать их в качестве внутренних частных классов, вы можете «ввести» их вручную.
Вам нужно будет создать метод с @PostInit
аннотация и инициализируйте свой a
Поле там (a = new MapperA ()
например, или что -то более сложное). С помощью этого подхода также следует проверить, что обратные вызовы инициализации включаются в вашей конфигурации пружины.