← Назад к вопросам

Чем является контекст в Spring?

2.2 Middle🔥 131 комментариев
#Spring Boot и Spring Data#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ApplicationContext в Spring

Определение

ApplicationContext — это центральный интерфейс Spring Framework. Он представляет IoC (Inversion of Control) контейнер, который управляет жизненным циклом объектов (beans), внедрением зависимостей и конфигурацией приложения.

Простыми словами: ApplicationContext — это контейнер, который создаёт объекты, управляет ими и внедряет зависимости между ними.

Что такое контейнер?

// БЕЗ Spring (ручное управление объектами)
public class MyApp {
    public static void main(String[] args) {
        // Нужно вручную создавать и связывать объекты
        UserRepository repo = new UserRepository();
        UserService service = new UserService(repo);
        UserController controller = new UserController(service);
        
        // И если UserRepository нужна база данных?
        // А базе нужен connection pool?
        // Это становится кошмаром
    }
}

// С Spring (контейнер управляет объектами)
public class MyApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // Контейнер сам создал все объекты и внедрил зависимости!
        UserController controller = context.getBean(UserController.class);
    }
}

ApplicationContext vs BeanFactory

// BeanFactory — минимальный функционал
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
MyBean bean = (MyBean) beanFactory.getBean("myBean");

// ApplicationContext — полнофункциональный контейнер
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean bean = context.getBean(MyBean.class);

// ApplicationContext делает больше:
// - Загружает конфигурацию
// - Инициализирует все beans при запуске
// - Поддерживает AOP
// - Поддерживает event publishing
// - Интегрируется с ресурсами (i18n, свойства)

Типы ApplicationContext

ClassPathXmlApplicationContext — из XML на классовом пути

ApplicationContext context = new ClassPathXmlApplicationContext(
    "applicationContext.xml"
);

// applicationContext.xml
/*
<beans xmlns="http://www.springframework.org/schema/beans">
    <bean id="userRepository" class="com.example.UserRepository"/>
    <bean id="userService" class="com.example.UserService">
        <constructor-arg ref="userRepository"/>
    </bean>
</beans>
*/

FileSystemXmlApplicationContext — из XML файла в файловой системе

ApplicationContext context = new FileSystemXmlApplicationContext(
    "/home/user/config/applicationContext.xml"
);

AnnotationConfigApplicationContext — из Java конфигурации

@Configuration
public class AppConfig {
    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
    
    @Bean
    public UserService userService(UserRepository repository) {
        return new UserService(repository);
    }
}

// Создание контекста
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService service = context.getBean(UserService.class);

AnnotationConfigWebApplicationContext — для веб-приложений (Spring Boot)

// Spring Boot автоматически создаёт контекст
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
        // Spring Boot создаёт AnnotationConfigWebApplicationContext
    }
}

Жизненный цикл контекста

public class LifecycleDemo {
    public static void main(String[] args) {
        // 1. Создание контекста
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println("Контекст создан");
        
        // 2. Получение bean
        UserService service = context.getBean(UserService.class);
        service.doSomething();
        
        // 3. Закрытие контекста (вызов destroy методов)
        if (context instanceof ConfigurableApplicationContext) {
            ((ConfigurableApplicationContext) context).close();
        }
    }
}

// Жизненный цикл bean
public class MyBean implements InitializingBean, DisposableBean {
    
    public MyBean() {
        System.out.println("1. Constructor called");
    }
    
    @PostConstruct
    public void init() {
        System.out.println("2. @PostConstruct init method");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("3. InitializingBean.afterPropertiesSet()");
    }
    
    public void doSomething() {
        System.out.println("4. Bean is working");
    }
    
    @PreDestroy
    public void cleanup() {
        System.out.println("5. @PreDestroy cleanup");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("6. DisposableBean.destroy()");
    }
}

Получение beans из контекста

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// По типу класса
UserService service = context.getBean(UserService.class);

// По имени bean
UserService service = (UserService) context.getBean("userService");

// По имени и типу
UserService service = context.getBean("userService", UserService.class);

// Получить все beans определённого типа
Map<String, UserRepository> repos = context.getBeansOfType(UserRepository.class);

// Получить все beans
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
    System.out.println(name);
}

// Проверить наличие bean
if (context.containsBean("userService")) {
    System.out.println("Bean exists");
}

Scopes (Области видимости bean)

public class BeanScopesExample {
    
    // Singleton (по умолчанию) — один объект на весь контекст
    @Bean
    @Scope("singleton")
    public UserService singletonService() {
        return new UserService();
    }
    
    // Prototype — новый объект при каждом запросе
    @Bean
    @Scope("prototype")
    public UserRepository prototypeRepository() {
        return new UserRepository();
    }
    
    // Request — один объект на HTTP request (веб)
    @Bean
    @Scope("request")
    public RequestContext requestContext() {
        return new RequestContext();
    }
    
    // Session — один объект на HTTP session
    @Bean
    @Scope("session")
    public SessionData sessionData() {
        return new SessionData();
    }
}

// Тестирование
public void testScopes() {
    ApplicationContext context = new AnnotationConfigApplicationContext(BeanScopesExample.class);
    
    // Singleton — одинаковые объекты
    UserService s1 = context.getBean(UserService.class);
    UserService s2 = context.getBean(UserService.class);
    System.out.println(s1 == s2);  // true
    
    // Prototype — разные объекты
    UserRepository r1 = context.getBean(UserRepository.class);
    UserRepository r2 = context.getBean(UserRepository.class);
    System.out.println(r1 == r2);  // false
}

Dependency Injection через контекст

@Configuration
public class AppConfig {
    
    // 1. Constructor Injection
    @Bean
    public UserService userService(UserRepository repository) {
        return new UserService(repository);  // Контекст вмешит зависимость
    }
    
    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
}

// 2. Annotation-based Injection
public class UserService {
    private UserRepository repository;
    
    @Autowired
    public void setRepository(UserRepository repository) {
        this.repository = repository;
    }
}

// 3. Field Injection
public class UserController {
    @Autowired
    private UserService userService;  // Контекст внедрит значение
}

Event Publishing (особенность ApplicationContext)

// Определяем custom event
public class UserCreatedEvent extends ApplicationEvent {
    private String userName;
    
    public UserCreatedEvent(Object source, String userName) {
        super(source);
        this.userName = userName;
    }
    
    public String getUserName() {
        return userName;
    }
}

// Listener
@Component
public class UserCreatedListener implements ApplicationListener<UserCreatedEvent> {
    @Override
    public void onApplicationEvent(UserCreatedEvent event) {
        System.out.println("User created: " + event.getUserName());
        // Отправляем email, логируем, etc.
    }
}

// Publishing event
@Component
public class UserService {
    @Autowired
    private ApplicationContext context;
    
    public void createUser(String name) {
        // Создаём пользователя
        User user = new User(name);
        
        // Публикуем event
        context.publishEvent(new UserCreatedEvent(this, name));
    }
}

Выводы

  1. ApplicationContext — IoC контейнер, управляет beans и зависимостями
  2. Основные типы контекста:
    • ClassPathXmlApplicationContext
    • FileSystemXmlApplicationContext
    • AnnotationConfigApplicationContext
    • AnnotationConfigWebApplicationContext (Spring Boot)
  3. Контекст управляет:
    • Созданием объектов
    • Внедрением зависимостей
    • Жизненным циклом beans
    • Публикацией событий
  4. Получение beans: getBean(), getBeansOfType(), getBeanDefinitionNames()
  5. Scopes: singleton, prototype, request, session
Чем является контекст в Spring? | PrepBro