← Назад к вопросам
Для чего нужна аннотация @Configuration?
1.8 Middle🔥 141 комментариев
#Spring Framework
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего нужна аннотация @Configuration
@Configuration — это ключевая аннотация Spring Framework, которая обозначает класс как источник определения бинов (bean definitions) для контейнера IoC.
Основное предназначение
// @Configuration обозначает класс конфигурации
@Configuration
public class AppConfig {
// @Bean обозначает методы, которые создают бины
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
// Spring автоматически создаст бины и добавит их в контейнер
Как @Configuration работает
- Spring сканирует приложение и находит классы с @Configuration
- Для каждого класса Spring создает специальный прокси (cglib proxy)
- Прокси перехватывает вызовы методов с @Bean аннотацией
- Результаты кэшируются так, чтобы один и тот же бин возвращался всегда
- Методы с параметрами получают зависимости из контейнера автоматически
@Configuration
public class DatabaseConfig {
@Bean
public DataSource dataSource() {
System.out.println("Creating DataSource");
return new HikariDataSource();
}
@Bean
public UserRepository userRepository(DataSource dataSource) {
// dataSource будет автоматически введен
// Это тот же бин, что был создан выше (синглтон)
return new UserRepository(dataSource);
}
}
// При запуске Spring:
// 1. Creating DataSource (выводится один раз)
// 2. userRepository получает то же самое DataSource
@Configuration vs без аннотации
Без @Configuration (НЕПРАВИЛЬНО)
public class BadConfig {
@Bean
public DataSource dataSource() {
System.out.println("Creating DataSource");
return new HikariDataSource();
}
@Bean
public UserRepository userRepository(DataSource dataSource) {
return new UserRepository(dataSource);
}
@Bean
public OrderRepository orderRepository() {
// Проблема: создает НОВЫЙ DataSource вместо использования бина!
DataSource ds = dataSource(); // Обычный вызов метода
return new OrderRepository(ds);
}
}
// Результат:
// - Creating DataSource выведется ДВАЖДЫ или ТРИЖДЫ
// - Разные компоненты получат разные DataSource'ы (не синглтон!)
// - Может привести к утечкам ресурсов
С @Configuration (ПРАВИЛЬНО)
@Configuration // Spring обернет класс в прокси
public class GoodConfig {
@Bean
public DataSource dataSource() {
System.out.println("Creating DataSource");
return new HikariDataSource();
}
@Bean
public UserRepository userRepository(DataSource dataSource) {
// dataSource пришел из контейнера
return new UserRepository(dataSource);
}
@Bean
public OrderRepository orderRepository(DataSource dataSource) {
// Тот же dataSource благодаря @Configuration
return new OrderRepository(dataSource);
}
}
// Результат:
// - Creating DataSource выведется один раз
// - Все компоненты используют один синглтон DataSource
// - Правильное управление ресурсами
Аннотация @Bean
Аннотация @Bean обозначает метод, который производит бин для контейнера:
@Configuration
public class AppConfig {
// Стандартное использование
@Bean
public UserService userService() {
return new UserService();
}
// С явным именем бина
@Bean(name = "primaryDataSource")
public DataSource dataSource() {
return new HikariDataSource();
}
// С инициализацией и очисткой
@Bean(initMethod = "init", destroyMethod = "cleanup")
public Cache cache() {
return new RedisCache();
}
// С условием
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new CacheManager();
}
}
Внедрение зависимостей в методы
@Configuration
public class ServiceConfig {
@Bean
public DatabaseConnection dbConnection() {
return new DatabaseConnection();
}
// Способ 1: параметр метода
@Bean
public UserService userService(DatabaseConnection conn) {
return new UserService(conn);
}
// Способ 2: конструктор конфига (если нужна одна зависимость)
private final AppProperties appProps;
public ServiceConfig(AppProperties appProps) {
this.appProps = appProps;
}
@Bean
public EmailService emailService() {
return new EmailService(appProps.getSmtpServer());
}
}
Полный пример приложения
// application.properties
// spring.datasource.url=jdbc:mysql://localhost:3306/mydb
// spring.datasource.username=root
// spring.datasource.password=password
@Configuration
public class ApplicationConfig {
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("password");
return new HikariDataSource(config);
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
public UserRepository userRepository(JdbcTemplate jdbcTemplate) {
return new UserRepository(jdbcTemplate);
}
@Bean
public UserService userService(UserRepository userRepository) {
return new UserService(userRepository);
}
}
// Использование в приложении
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class);
// Получить бин
UserService userService = context.getBean(UserService.class);
userService.createUser("john");
}
}
@Configuration vs @Component
// @Component
@Component
public class SimpleComponent {
// Это просто компонент, Spring создает один экземпляр
}
// @Configuration
@Configuration
public class ConfigClass {
@Bean
public SomeService someService() {
return new SomeService();
}
}
// Разница:
// - @Component: сам по себе бин
// - @Configuration: класс с методами, которые создают бины
// - @Configuration обертывается в прокси для правильного кэширования
Nested @Configuration
@Configuration
public class OuterConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
@Configuration
public static class InnerConfig {
@Bean
public UserRepository userRepository(DataSource dataSource) {
return new UserRepository(dataSource);
}
}
}
Важные особенности
- Синглтоны по умолчанию
@Configuration
public class Config {
@Bean
public MyService myService() {
return new MyService(); // Создается один раз и кэшируется
}
}
- Автоматическое разрешение зависимостей
@Bean
public B beanB(A beanA) { // beanA автоматически внедряется
return new B(beanA);
}
- Порядок инициализации
@Bean
public DataSource dataSource() { ... }
@Bean
public JdbcTemplate jdbcTemplate(DataSource ds) {
// dataSource будет создан ДО этого метода
return new JdbcTemplate(ds);
}
Современная альтернатива
В Spring Boot 3.0+ можно использовать @Configuration с proxyBeanMethods = false для лучшей производительности:
@Configuration(proxyBeanMethods = false)
public class FastConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
// Важно: если вам НЕ нужна гарантия синглтонов от прокси
Итог
@Configuration — это мощная аннотация, которая:
- Обозначает класс как источник конфигурации
- Позволяет определять бины через методы
- Гарантирует синглтоны и правильное кэширование благодаря прокси
- Обеспечивает автоматическое разрешение зависимостей
- Создает декларативную конфигурацию приложения
Это один из основных механизмов, благодаря которому Spring Framework реализует инверсию управления (IoC) и внедрение зависимостей (DI).