У меня есть график Spring bean-компонентов, которые автоматически подключаются друг к другу. Сильно упрощенная иллюстрация:
...
public class Foo {
@Autowired Bar bar;
@Autowired Baz baz;
}
public class Bar {
@Autowired Foo foo;
}
public class Baz {
@Autowired Foo foo;
}
У всех этих bean-компонентов не указана область действия, что подразумевает, что они являются синглтонами (, делая их явными синглтонами, ничего не меняется, я пробовал ).
Проблема заключается в том, что после создания экземпляра одного контекста приложения экземпляры Bar
и Baz
содержат разные экземпляры Foo
. Как такое могло произойти?
Я попытался создать общедоступный конструктор без аргументов для Foo
, и отладка подтвердила, что Foo
создается более одного раза. Трассировка стека для всех этих творений — здесь .
Я также попытался включить ведение журнала отладки для Spring,и среди всех других строк получил следующее:
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'Foo'
Я понимаю, что мои bean-компоненты перекрестно -ссылаются друг на друга, но я ожидаю, что Spring framework будет уважать одноэлементную область действия и инициализировать одноэлементный bean-компонент один раз, а затем автоматически связывать его с тем, кто этого захочет.
Интересный факт, что если я использую конструктор старой школы private
с аксессором public static Foo getInstance
, это работает просто отлично -во время настройки контекста исключений не возникает.
FWIW, я использую Spring версии 3.0.5 (, также пробовал с 3.1.2, те же результаты )с конструктором o.s.c.s.ClassPathXmlApplicationContext(String...configLocations)
.
Я могу легко преобразовать свой код для использования статического инициализатора, но я хочу понять, почему Spring ведет себя таким образом. Это ошибка?
РЕДАКТИРОВАТЬ:Некоторые дополнительные исследования показали, что
context.getBean(Foo.class)
всегда возвращает один и тот же экземпляр Foo
.@Autowired
сеттерами (около 20 использований этого bean-компонента )по-прежнему приводит к многочисленным конструкциям этого объекта, но все зависимости вводятся с одной и той же ссылкой .Мне выше кажется, что это ошибка Spring, относящаяся к реализации @Autowired
. Я собираюсь опубликовать сообщение на форумах сообщества Spring и опубликовать здесь, если мне удастся получить что-нибудь полезное.