Что такое @Configuration класс?
4. @Bean → для сторонних библиотек 5. Наследование → бины родителя тоже регистрируются 6. ConfigurationClassPostProcessor → обработка на ранней стадии
🟢 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
- proxyBeanMethods = false — по умолчанию для новых проектов, НО если @Bean методы вызывают друг друга — оставьте true (иначе сломается singleton).
- Аргументы методов → вместо вызовов других @Bean
- Не final → классы и методы
- @Bean → для сторонних библиотек
- Наследование → бины родителя тоже регистрируются
- 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]]