Я пытаюсь разобраться в инициализации bean-компонентов Spring на основе аннотаций. Итак, у меня есть класс, в котором есть несколько объявлений bean-компонентов, и некоторые bean-компоненты требуются другим bean-компонентам. У меня возникает вопрос: если бы я напрямую использовал метод bean-компонента в другом методе bean-фабрики, Spring правильно обработал бы его и внедрил требуемый bean-компонент, или в конечном итоге я создал бы несколько экземпляров внедренного bean-компонента?
Образец кода
@Configuration
class Config {
@Bean
public SomeBean someBean() {
// some builder code
return someBean;
}
@Bean
public AnotherBean anotherBean() {
return anotherBeanBuilder
.withSomeBean(someBean())
.build();
}
}
Итак, если я перефразирую свой вопрос на основе приведенного выше примера, я хочу знать, что, по сути, когда я использую anotherBean() в каком-то другом месте, Spring будет правильно использовать уже созданный someBean или в конечном итоге создаст несколько экземпляров SomeBean.
Иногда у вас нет выбора, например, в некоторых конфигураторах, таких как SpringMVC или Spring Security. Если у вас есть выбор, поступайте так, как предлагает @M.Deinum.
Spring MVC ничего подобного не предотвращает, равно как и Spring Security (особенно новая версия конфигурации).




Spring создает специальные прокси для классов @Configuration. Фактически метод вызывается только один раз. Проверить свою гипотезу самостоятельно довольно легко:
@Configuration
class Config {
@Bean
public SomeBean someBean() {
final SomeBean bean;
System.out.println("created someBean: " + bean);
return bean;
}
@Bean
public AnotherBean anotherBean() {
System.out.println(someBean()); // SomeBean@cafe0420 (example)
System.out.println(someBean());
System.out.println(someBean());
return new AnotherBean(someBean());
}
}
class SomeBean {}
class AnotherBean { AnotherBean(SomeBean bean) {} }
Выход:
created someBean: SomeBean@cafe0420
SomeBean@cafe0420
SomeBean@cafe0420
SomeBean@cafe0420
Итак, как вы можете видеть, вызов метода класса конфигурации вернет тот же один экземпляр компонента (на самом деле он вообще не вызывает метод).
Дополнительные ресурсы:
Да, это так. Но лучше просто внедрить компонент в метод в качестве аргумента, поскольку это облегчит Spring определение зависимостей между компонентами и обеспечит правильный порядок установки.