Ответ
По умолчанию Spring создает бины в singleton scope (один экземпляр на контейнер). Несколько экземпляров требуются в следующих сценариях:
-
Прототипные (prototype) бины: Когда состояние бина не должно разделяться между запросами.
@Component @Scope("prototype") // Каждый запрос на внедрение/получение создает новый объект public class ShoppingCart { private List<Item> items = new ArrayList<>(); // У каждого пользователя/сессии своя корзина } -
Несколько реализаций одного интерфейса с разной конфигурацией:
@Configuration public class DataSourceConfig { @Bean @Primary // Основной бин для автопривязки без @Qualifier public DataSource primaryDataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://host1/db") .username("user1") .build(); } @Bean public DataSource secondaryDataSource() { return DataSourceBuilder.create() .url("jdbc:mysql://host2/db") .username("user2") .build(); } }Использование с
@Qualifier:@Service public class ReportingService { private final DataSource readOnlyDataSource; private final DataSource writeDataSource; public ReportingService( @Qualifier("secondaryDataSource") DataSource readOnlyDataSource, @Qualifier("primaryDataSource") DataSource writeDataSource) { this.readOnlyDataSource = readOnlyDataSource; this.writeDataSource = writeDataSource; } } -
Бины, зависящие от внешнего контекста (например, HTTP-запроса или сессии):
@Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class UserPreferences { // У каждого HTTP-сеанса будет свой экземпляр } -
Создание бинов динамически, на основе условий:
@Configuration public class DynamicBeanConfig { @Bean @ConditionalOnProperty(name = "cache.provider", havingValue = "redis") public CacheManager redisCacheManager() { /* ... */ } @Bean @ConditionalOnProperty(name = "cache.provider", havingValue = "caffeine") public CacheManager caffeineCacheManager() { /* ... */ } }
Ключевые аннотации и подходы:
@Scope("prototype")– для создания нового экземпляра при каждом запросе.@Qualifier("имяБина")– для выбора конкретной реализации при внедрении зависимости.@Primary– чтобы пометить бин по умолчанию.- Условное создание бинов (
@Conditional,@Profile) – для создания разных бинов в разных средах.