Почему @Configuration — это не просто @Component?
Почему @Configuration — это не просто @Component?
Часто спрашивают:
Как правило отвечают:
Формально да, но интерес начинается вот здесь:
Кажется, что внутри paymentService() и мы просто каждый раз вызываем обычный Java-метод. Но это не так, в классическом режиме Spring перехватывает такой вызов и возвращает тот же Bean из контейнера. То есть:
orderService()
↓
paymentService()
↓
Spring Container
↓
тот же PaymentService
А не создаёт новый new PaymentService()
Именно поэтому @Configuration — это не просто «класс с настройками».
Spring может использовать специальный механизм проксирования @Configuration, чтобы вызовы @Bean-методов проходили через контейнер. Теперь самое интересное.
Можно написать:
@Configuration(proxyBeanMethods = false)
public class AppConfig {
...
}
И поведение меняется, тут Spring не будет перехватывать прямые вызовы @Bean-методов внутри конфигурационного класса.
То есть paymentService() становится обычным вызовом Java-метода, это может привести к созданию нового объекта, если метод действительно создаёт его через new.
Зачем тогда вообще proxyBeanMethods = false? - Чтобы отказаться от этого дополнительного проксирования, когда оно не нужно.
Например, если @Bean-методы не вызывают друг друга напрямую:
@Configuration(proxyBeanMethods = false)
public class AppConfig {
@Bean
public PaymentService paymentService() {
return new PaymentService();
}
@Bean
public OrderRepository orderRepository() {
return new OrderRepository();
}
}
Здесь такой режим вполне логичен. Получается, что @Configuration — это не просто более красивый @Component, у него есть специальная семантика для @Bean-методов и вопрос:
уже гораздо интереснее, чем:
Потому что здесь нужно понимать не только аннотации, но и как Spring управляет объектами внутри контейнера.
Часто спрашивают:
Чем @Configuration отличается от @Component?
Как правило отвечают:
«@Configuration — для конфигурации, @Component — для компонентов».
Формально да, но интерес начинается вот здесь:
@Configuration
public class AppConfig {
@Bean
public PaymentService paymentService() {
return new PaymentService();
}
@Bean
public OrderService orderService() {
return new OrderService(paymentService());
}
}
Кажется, что внутри paymentService() и мы просто каждый раз вызываем обычный Java-метод. Но это не так, в классическом режиме Spring перехватывает такой вызов и возвращает тот же Bean из контейнера. То есть:
orderService()
↓
paymentService()
↓
Spring Container
↓
тот же PaymentService
А не создаёт новый new PaymentService()
Именно поэтому @Configuration — это не просто «класс с настройками».
Spring может использовать специальный механизм проксирования @Configuration, чтобы вызовы @Bean-методов проходили через контейнер. Теперь самое интересное.
Можно написать:
@Configuration(proxyBeanMethods = false)
public class AppConfig {
...
}
И поведение меняется, тут Spring не будет перехватывать прямые вызовы @Bean-методов внутри конфигурационного класса.
То есть paymentService() становится обычным вызовом Java-метода, это может привести к созданию нового объекта, если метод действительно создаёт его через new.
Зачем тогда вообще proxyBeanMethods = false? - Чтобы отказаться от этого дополнительного проксирования, когда оно не нужно.
Например, если @Bean-методы не вызывают друг друга напрямую:
@Configuration(proxyBeanMethods = false)
public class AppConfig {
@Bean
public PaymentService paymentService() {
return new PaymentService();
}
@Bean
public OrderRepository orderRepository() {
return new OrderRepository();
}
}
Здесь такой режим вполне логичен. Получается, что @Configuration — это не просто более красивый @Component, у него есть специальная семантика для @Bean-методов и вопрос:
«Что делает proxyBeanMethods?»
уже гораздо интереснее, чем:
«Что такое @Configuration?»
Потому что здесь нужно понимать не только аннотации, но и как Spring управляет объектами внутри контейнера.