Что такое ApplicationContext в Spring Framework?

Ответ

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

ApplicationContext является расширением более простого интерфейса BeanFactory, добавляя следующие возможности:

  • Интеграция с AOP (аспектно-ориентированным программированием).
  • Управление ресурсами (ResourceLoader) для удобной работы с файлами, URL и т.д.
  • Публикация и обработка событий (ApplicationEventPublisher).
  • Поддержка интернационализации (i18n) сообщений.
  • Наследование контекстов (родительский-дочерний).
  • Автоматическое обнаружение и регистрация бинов через аннотации (@ComponentScan).

Основные реализации ApplicationContext:

  • AnnotationConfigApplicationContext: Для конфигурации на Java-классах с аннотациями (@Configuration).
  • ClassPathXmlApplicationContext: Для конфигурации через XML-файлы, загружаемые из classpath.
  • FileSystemXmlApplicationContext: Аналогично предыдущему, но XML загружается из файловой системы.
  • WebApplicationContext: Специализированный контекст для веб-приложений (используется в Spring MVC).

Пример создания и использования:

// 1. Создание контекста из Java-конфигурации
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// 2. Получение бина по типу (рекомендуемый способ)
UserService userService = context.getBean(UserService.class);

// 3. Получение бина по имени и типу
DataSource dataSource = context.getBean("primaryDataSource", DataSource.class);

// 4. Проверка существования бина
boolean exists = context.containsBean("myBean");

// 5. Получение всех бинов определенного типа
Map<String, Validator> validators = context.getBeansOfType(Validator.class);

// 6. Публикация события
context.publishEvent(new MyCustomEvent(this, "Данные обновлены"));

Контекст инициализируется один раз при старте приложения (обычно в ServletContextListener для веб-приложений), загружает все определения бинов и затем обслуживает запросы, предоставляя готовые экземпляры.

Ответ 18+ 🔞

Слушай, ну вот представь себе такую картину. Есть у тебя приложение, да? И там куча этих… объектов, классов, зависимостей — пиздец какой-то зоопарк. И все они друг другу нужны, друг на друга ссылаются, друг друга создают. И если ты будешь это всё вручную, в коде, как дурак, собирать — это ж, блядь, на неделю работы, и ещё потом полгода отлаживать, почему NullPointerException вылез.

Так вот, ApplicationContext в Spring — это такой, понимаешь, главный завхоз, ёбаный складской менеджер высшей категории. Его задача — взять на себя всю эту хуйню: создать все объекты (они там «бинами» зовутся), настроить их, связать между собой (это и есть тот самый контейнер IoC — инверсия управления) и потом по первому твоему требованию тебе нужный экземпляр выдать. Ты не управляешь жизнью объектов — контекст всем заправляет. Красота, да?

А самое охуенное, что это не просто какая-то тупая фабрика. ApplicationContext — это прокачанный наследник более простого интерфейса BeanFactory. Он умеет не только бины штамповать, а ещё кучу всего:

  • AOP подвезти — навесить на твои методы логирование или транзакции, не залезая в код.
  • Ресурсы грузить (ResourceLoader) — файлы, свойства, URL-ы, не паришься откуда.
  • События разводить (ApplicationEventPublisher) — один компонент крикнул «ой, всё!», а другие его услышали и отреагировали.
  • Интернационализацию — чтобы «Hello, world» на хинди вывести.
  • Автоматически сканировать проект и находить классы с аннотациями типа @Service, @Component — не надо вручную каждый бин прописывать.

Из каких, блядь, кирпичей этот контекст собирается? Основные реализации:

  • AnnotationConfigApplicationContext: Современный способ. Ты пишешь Java-класс с @Configuration, накидываешь аннотаций — и он всё понимает. Модно, молодёжно.
  • ClassPathXmlApplicationContext: Старая школа. Всё прописано в XML-файле, который лежит где-то в недрах classpath. Ещё живой, но уже пахнет нафталином.
  • FileSystemXmlApplicationContext: То же самое, но XML ищешь по конкретному пути в файловой системе.
  • WebApplicationContext: Спецверсия для веб-приложений. Живёт внутри сервлет-контейнера и знает про ServletContext.

Ну и как этим пользоваться-то, на практике? Да элементарно, ёпта!

// 1. Запускаем движок! Создаём контекст из Java-конфига.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// 2. "Дайте мне, пожалуйста, UserService". Контекст тебе его уже приготовил.
UserService userService = context.getBean(UserService.class);

// 3. "А можно тот DataSource, который 'primaryDataSource'?" Можно, на.
DataSource dataSource = context.getBean("primaryDataSource", DataSource.class);

// 4. "А бин с именем 'myBean' вообще существует?" Сейчас проверим, сука.
boolean exists = context.containsBean("myBean");

// 5. "Дайте мне ВСЕ валидаторы, какие есть!" Получай мешок бинов.
Map<String, Validator> validators = context.getBeansOfType(Validator.class);

// 6. "Внимание, внимание! Произошло событие!" Все, кто подписан, отреагируют.
context.publishEvent(new MyCustomEvent(this, "Данные обновлены"));

Важный момент, блядь: Контекст инициализируется один раз, обычно при старте приложения. Он, как упоротый перфекционист, поднимает все бины, связывает их, проверяет — и только потом говорит «окей, готов к работе». В веб-приложении это часто делается где-то в ServletContextListener. А дальше он просто стоит и обслуживает запросы, выдавая тебе готовые, настроенные экземпляры. Удобно же, а?