Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Как управлять контекстом в Spring Boot
Что такое ApplicationContext
ApplicationContext — это центральный объект Spring, который управляет всеми бинами, конфигурацией и жизненным циклом приложения.
1. Доступ к ApplicationContext через Autowiring
@Component
public class ContextAccessor {
private final ApplicationContext applicationContext;
// Внедрение ApplicationContext
public ContextAccessor(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void printAllBeans() {
String[] beanNames = applicationContext.getBeanDefinitionNames();
for (String name : beanNames) {
System.out.println("Bean: " + name);
}
}
public <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public Object getBean(String name) {
return applicationContext.getBean(name);
}
}
2. ApplicationContextAware (для полного доступа)
@Component
public class ContextAwareComponent implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.applicationContext = context;
}
public void displayContextInfo() {
System.out.println("Application name: " + applicationContext.getApplicationName());
System.out.println("Display name: " + applicationContext.getDisplayName());
System.out.println("Bean count: " + applicationContext.getBeanDefinitionCount());
}
}
3. Программное создание контекста
public class ManualContextCreation {
public static void main(String[] args) {
// Создание контекста вручную (без Spring Boot)
ApplicationContext context = new ClassPathXmlApplicationContext(
"application-context.xml"
);
UserService userService = context.getBean(UserService.class);
userService.doSomething();
// Закрытие контекста
((ClassPathXmlApplicationContext) context).close();
}
}
4. Аннотационная конфигурация контекста
@Configuration
public class AppConfiguration {
@Bean
public UserRepository userRepository() {
return new UserRepository();
}
@Bean
public UserService userService(UserRepository repository) {
return new UserService(repository);
}
@Bean
public DataSource dataSource() {
return DataSourceBuilder.create()
.driverClassName("org.postgresql.Driver")
.url("jdbc:postgresql://localhost/mydb")
.username("user")
.password("password")
.build();
}
}
5. Spring Boot ApplicationBuilder
public class CustomBootApplication {
public static void main(String[] args) {
ApplicationContext context = new SpringApplicationBuilder()
.sources(MyApplication.class)
.properties("spring.config.location=classpath:custom.properties")
.bannerMode(Banner.Mode.OFF)
.run(args);
MyService service = context.getBean(MyService.class);
}
}
@SpringBootApplication
public class MyApplication {}
6. Управление профилями (Profiles)
@Configuration
public class ProfileConfiguration {
@Bean
@Profile("dev")
public DataSource devDataSource() {
return DataSourceBuilder.create()
.driverClassName("org.h2.Driver")
.url("jdbc:h2:mem:testdb")
.build();
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
return DataSourceBuilder.create()
.driverClassName("org.postgresql.Driver")
.url("jdbc:postgresql://prod-db:5432/db")
.build();
}
}
@Component
public class ProfileAwareService implements EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public String getActiveProfile() {
String[] profiles = environment.getActiveProfiles();
return profiles.length > 0 ? profiles[0] : "default";
}
}
7. Условная регистрация бинов (@Conditional)
@Component
@ConditionalOnProperty(
name = "feature.caching.enabled",
havingValue = "true"
)
public class CacheService {
public void enableCaching() {
System.out.println("Кеш включён");
}
}
@Component
@ConditionalOnClass(name = "com.redis.Redis")
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate() {
return new RedisTemplate<>();
}
}
@Component
@ConditionalOnMissingBean(CacheService.class)
public class DefaultCacheService implements CacheService {}
8. Слушатели контекста (Context Listeners)
@Component
public class AppContextListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("ApplicationContext инициализирован");
ApplicationContext context = event.getApplicationContext();
// Выполняем инициализацию
}
}
@Component
public class AppCloseListener implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.println("ApplicationContext закрывается");
// Очистка ресурсов
}
}
9. Фильтрация и получение бинов
@Component
public class BeanFinder {
private final ApplicationContext context;
public BeanFinder(ApplicationContext context) {
this.context = context;
}
// Получить все бины определённого типа
public void findAllOfType() {
Map<String, UserService> beans = context.getBeansOfType(UserService.class);
beans.forEach((name, bean) -> System.out.println(name + ": " + bean));
}
// Проверить наличие бина
public void checkBean() {
if (context.containsBean("userService")) {
System.out.println("userService существует");
}
}
// Получить бин по имени с типом
public UserService getUserService() {
return context.getBean("userService", UserService.class);
}
// Получить бины с аннотацией
public void findAnnotatedBeans() {
Map<String, Object> beans = context.getBeansWithAnnotation(Service.class);
beans.forEach((name, bean) -> System.out.println(name));
}
}
10. Refresh контекста (перезагрузка)
@Component
public class ContextManager {
private final ConfigurableApplicationContext context;
public ContextManager(ConfigurableApplicationContext context) {
this.context = context;
}
public void reloadContext() {
try {
context.refresh();
System.out.println("Контекст перезагружен");
} catch (Exception e) {
System.err.println("Ошибка при перезагрузке: " + e.getMessage());
}
}
public void closeContext() {
context.close();
System.out.println("Контекст закрыт");
}
public boolean isRunning() {
return context.isRunning();
}
}
11. Иерархия контекстов (Parent-Child)
public class HierarchicalContextExample {
public static void main(String[] args) {
// Родительский контекст
ApplicationContext parentContext = new ClassPathXmlApplicationContext(
"parent-context.xml"
);
// Дочерний контекст
ClassPathXmlApplicationContext childContext =
new ClassPathXmlApplicationContext(
new String[]{"child-context.xml"},
parentContext // Передаём родителя
);
// Дочерний контекст может получать бины у родителя
UserService userService = childContext.getBean(UserService.class);
}
}
12. Event Publishing (событие в контексте)
// Определение события
public class UserCreatedEvent extends ApplicationEvent {
private final User user;
public UserCreatedEvent(Object source, User user) {
super(source);
this.user = user;
}
public User getUser() {
return user;
}
}
// Публикация события
@Service
public class UserService {
private final ApplicationEventPublisher eventPublisher;
public UserService(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void createUser(User user) {
repository.save(user);
// Публикуем событие в контексте
eventPublisher.publishEvent(new UserCreatedEvent(this, user));
}
}
// Слушатель события
@Component
public class UserCreatedListener {
@EventListener
public void onUserCreated(UserCreatedEvent event) {
User user = event.getUser();
System.out.println("Новый пользователь: " + user.getName());
}
}
13. Properties и Environment
@Component
public class PropertyManager {
private final Environment environment;
public PropertyManager(Environment environment) {
this.environment = environment;
}
public String getDatabaseUrl() {
return environment.getProperty("spring.datasource.url");
}
public int getDatabasePort() {
return environment.getProperty("spring.datasource.port", Integer.class, 5432);
}
public boolean isProduction() {
return environment.matchesProfiles("prod");
}
}
14. Registry для регистрации бинов во время выполнения
@Component
public class DynamicBeanRegistry {
private final ConfigurableApplicationContext context;
public DynamicBeanRegistry(ConfigurableApplicationContext context) {
this.context = context;
}
public void registerDynamicBean() {
// Получаем registry
DefaultListableBeanFactory factory =
(DefaultListableBeanFactory) context.getBeanFactory();
// Регистрируем бин во время выполнения
BeanDefinition beanDef = new RootBeanDefinition(MyDynamicService.class);
factory.registerBeanDefinition("dynamicService", beanDef);
MyDynamicService service = context.getBean("dynamicService", MyDynamicService.class);
}
}
Best Practices
- Предпочитай Dependency Injection вместо прямого доступа к контексту
- Используй @Configuration для явной конфигурации бинов
- Профили для разных окружений (dev, test, prod)
- Event Publishing для слабо связанного взаимодействия
- Слушатели контекста для инициализации при старте
- Избегай Static contexts — используй внедрение зависимостей
- Properties and Environment для конфигурации
- Избегай множественного refresh() — это дорого