Spring создает несколько экземпляров синглтона?

У меня есть график 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 и опубликовать здесь, если мне удастся получить что-нибудь полезное.

16
задан mindas 19 July 2012 в 10:25
поделиться