Весна: инъекция частного внутреннего класса в качестве участника внешнего класса?

StackOverflow https://stackoverflow.com/questions/2344463

  •  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>

РЕДАКТИРОВАТЬ: дополнительная информация, основанная на отзывах ответов:

  1. Я ленился с моим примером. У меня есть общедоступный сеттер/getter для переменной экземпляра Mapper.

  2. Причина, по которой все классы Mapper являются внутренними классами, заключается в том, что их потенциально может быть много из них, и они будут использоваться только в этом классе. Я просто не хочу кучу классов Cruft в моем проекте. Может быть, фабричный метод - лучшая идея.

Это было полезно?

Решение

Обычно вам нужен сеттер для Mapper в пределах Outer, и экземпляр необходимого Mapper. Анкет Но как это:

  1. частный
  2. внутренний

Занятия, это становится немного сложным (как вы идентифицировали). Если вы сделаете их публичными, я уверен, что вы сможете создать экземпляр, используя Outer$MapperA и т. д. Но это кажется немного противным. Так:

  1. Должны ли они быть внутренним и частным?
  2. Возможно, внешний может взять строку и определить из этого, создать ли экземпляры 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 () например, или что -то более сложное). С помощью этого подхода также следует проверить, что обратные вызовы инициализации включаются в вашей конфигурации пружины.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top