Питання 24 · Розділ 5

Що таке @Configuration клас?

4. @Bean → для сторонніх бібліотек 5. Наслідування → біни батька теж реєструються 6. ConfigurationClassPostProcessor → обробка на ранній стадії

Мовні версії: English Russian Ukrainian

🟢 Junior Level

@Configuration — клас, який створює біни через методи @Bean.

@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }

    @Bean
    public OrderController orderController() {
        return new OrderController(userService());  // Впровадження
    }
    // У Full mode (за замовчуванням) Spring перехопить виклик userService()
    // та поверне singleton. У Lite mode (proxyBeanMethods = false) створиться
    // новий об'єкт — див. Middle Level.
}

Навіщо:

  • Для сторонніх бібліотек (не можна поставити @Service)
  • Для складного налаштування бінів

🟡 Middle Level

Full vs Lite Mode

Full Mode (за замовчуванням):

@Configuration  // proxyBeanMethods = true
public class Config {
    @Bean public A a() { return new A(); }
    @Bean public B b() { return new B(a()); }  // Той самий екземпляр A!
}

// CGLIB проксі перехоплює виклик a()
// → Перевіряє кеш → повертає існуючий бін

Lite Mode:

@Configuration(proxyBeanMethods = false)
// або @Component, @Service з @Bean методами

@Bean public A a() { return new A(); }
@Bean public B b() { return new B(a()); }  // НОВИЙ екземпляр A!

// Немає проксі → прямий виклик методу

Коли proxyBeanMethods = false

// Використовуйте false, якщо:
// 1. @Bean методи не викликають один одного
// 2. Залежності через аргументи методів
@Bean
public Service service(Repo repo) {  // Spring сам знайде repo
    return new Service(repo);
}

// → Швидший старт
// → Менше пам'яті
// → GraalVM Native friendly

🔴 Senior Level

CGLIB Proxies

@Configuration → CGLIB підклас:
  → Перехоплює виклики @Bean методів
  → Перевіряє singletonObjects cache
  → Повертає існуючий або створює

→ Не можна final класи/методи! CGLIB створює підклас через наслідування.
  Якщо клас або метод final — Java не дозволяє наслідуватись/перевизначити,
  проксіювання неможливе, Spring кине помилку.
→ overhead на генерацію байт-коду

Наслідування

@Configuration
public class ParentConfig {
    @Bean public CommonBean common() { return new CommonBean(); }
}

@Configuration
public class ChildConfig extends ParentConfig {
    // common() бін теж зареєстрований!
}

Production Experience

Реальний сценарій: proxyBeanMethods = true сповільнював старт

200 @Configuration класів → 5 секунд на CGLIB
Рішення: proxyBeanMethods = false
Результат: старт 2 секунди

Best Practices

  1. proxyBeanMethods = false — за замовчуванням для нових проектів, АЛЕ якщо @Bean методи викликають один одного — залиште true (інакше зламається singleton).
  2. Аргументи методів → замість викликів інших @Bean
  3. Не final → класи та методи
  4. @Bean → для сторонніх бібліотек
  5. Наслідування → біни батька теж реєструються
  6. ConfigurationClassPostProcessor → обробка на ранній стадії

Резюме для Senior

  • @Configuration = фабрика бінів
  • Full mode → CGLIB проксі, singleton семантика
  • Lite mode → немає проксі, нові об’єкти
  • proxyBeanMethods = false → швидше, Native friendly
  • Аргументи методів → Spring сам впровадить
  • final → не можна проксіювати

🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • @Configuration клас створює біни через @Bean методи — для сторонніх бібліотек та складного налаштування
  • Full mode (proxyBeanMethods = true): CGLIB-проксі перехоплює виклики @Bean методів та повертає singleton
  • Lite mode (proxyBeanMethods = false): прямий виклик методу — кожен виклик створює новий об’єкт
  • Constructor Injection через аргументи @Bean методів — Spring сам впровадить залежності
  • CGLIB створює підклас через наслідування — не можна final класи/методи
  • proxyBeanMethods = false прискорює старт на 40-60% і потрібен для GraalVM Native Image
  • Наслідування @Configuration: біни батька теж реєструються

Часті уточнюючі запитання:

  • Коли використовувати proxyBeanMethods = false? — Коли @Bean методи не викликають один одного та залежності передаються через аргументи.
  • Що буде, якщо викликати @Bean метод безпосередньо в Lite mode? — Створиться новий екземпляр, singleton-семантика зламається.
  • Чому @Configuration клас не може бути final? — CGLIB створює підклас для проксіювання; final наслідування неможливе.
  • Чим @Configuration відрізняється від @Component з @Bean методами? — @Component працює в Lite mode — виклики @Bean методів не перехоплюються.

Червоні прапорці (НЕ говорити):

  • «@Bean методи завжди створюють singleton» — тільки в Full mode з проксі.
  • «proxyBeanMethods = false завжди краще» — ні, ламається singleton при між-@Bean викликах.
  • «@Configuration — це просто @Component» — ні, Full vs Lite mode критично відрізняються.
  • «Можна робити @Bean методи final» — ні, CGLIB не зможе перевизначити метод.

Пов’язані теми:

  • [[21. Як працює @SpringBootApplication]]
  • [[26. Що робить анотація @Autowired]]
  • [[28. Що таке @Qualifier]]
  • [[25. В чому різниця між @Component, @Service, @Repository, @Controller]]