- Контекст приложения Spring Boot
- Spring Application Context
- Получение контекста приложения
- Пример контекста приложения Spring Boot
- Приложение Spring Контекст
- Начните работу с Spring 5 и Spring Boot 2 с помощью справочного курса Изучите Spring :
- 1. Обзор
- Дополнительная литература:
- Данные Spring JPA @Query
- Spring Boot Error ApplicationContextException
- Ошибка загрузки ApplicationContext для теста JUnit контроллера Spring
- 2. Интерфейс ApplicationContext
- 3. Что такое bean-компонент Spring?
- 4. Настройка бинов в контейнере
- 4.1. Конфигурация на основе Java
- 4.2. Конфигурация на основе аннотаций
- 4.3. Конфигурация на основе XML
- 5. Типы Контекст приложения
- 5.1. AnnotationConfigApplicationContext
- 5.2. AnnotationConfigWebApplicationContext
- 5.3. XmlWebApplicationContext
- 5.4 . XML-контекст приложения файловой системы
- 5,5. Контекст приложения ClassPathXml
- 6 Еще особенности ApplicationContext
- 6.1. Интерфейс разрешения сообщений
- 6.2. Управление событиями
- 7. Заключение
- Spring: в поисках контекста
- Теория истории
- Конфигурация XML
- Конфигурация Groovy
- Конфигурация с использованием аннотаций, указывающих пакет для сканирования, или JavaConfig
- Выход
Контекст приложения Spring Boot
последнее изменение: 10 мая 2022 г.
Учебное пособие Spring Boot ApplicationContext показывает, как использовать ApplicationContext в приложении Spring Boot.
популярная платформа для создания корпоративных приложений на Java, Kotlin или Groovy.
Spring Application Context
является краеугольным камнем Spring Boot. Он представляет контейнер Spring IoC и отвечает за создание экземпляров, настройку и создание bean-компонентов. Контейнер получает инструкции о том, какие объекты создавать, настраивать и строить, считывая метаданные конфигурации. Метаданные конфигурации представлены в XML, аннотациях Java или коде Java.
ApplicationContext предоставляет следующее:
- Методы фабрики компонентов для доступа к компонентам приложения
- Возможность загрузки файловых ресурсов в целом
- Возможность публиковать события для зарегистрированных прослушивателей
- Возможность разрешения сообщений с поддержкой интернационализации
ApplicationContext имеет несколько реализаций. Например, ClassPathXmlApplicationContext берет конфигурацию из XML-файла по пути к классу или AnnotationConfigApplicationContext , который считывает конфигурацию с использованием аннотаций, особенно @Configuration .
Получение контекста приложения
Чтобы получить доступ к контексту приложения приложения, мы можем автоматически подключить интерфейс ApplicationContext или реализовать ApplicationContextAware .
Пример контекста приложения Spring Boot
В следующем приложении мы получаем доступ в контекст приложения, и мы используем его методы.
Это структура проекта приложения Spring Boot.
Это файл сборки Gradle. Spring-Boot-Starter — это основная программа запуска, которая включает автоконфигурацию, регистрацию и поддержку YAML. Приложение упаковано в файл JAR.
Файл application.yml содержит параметры конфигурации для приложения. Есть некоторые встроенные свойства приложения, и мы можем создать свои собственные. Свойство режима баннера является встроенным свойством Spring; мы свернем знамя весны. Мы можем отключить вход в систему, используя свойство log-startup-info. Name — это свойство для установки имени приложения
MyBean реализует ApplicationContextAware. Spring Boot помещает контекст приложения в параметр метода setApplicationContext(), где мы получаем идентификатор приложения Spring. (Идентификатор здесь — это имя приложения.)
В приложении мы создаем bean-компонент, вызываем его метод и настраиваем приложение Spring Boot. Интерфейс CommandLineRunner указывает, что компонент должен запускаться, если он содержится в SpringApplication. Его можно использовать для создания приложений командной строки в Spring Boot.
Аннотация @SpringBootApplication включает автоматическую настройку и сканирование компонентов. Spring Boot находит аннотацию MyBean и загружает ее в фабрику компонентов контекста приложения.
С аннотацией @Autowired мы вставляем наш компонент ApplicationContext в массив. Теперь у нас есть доступ к методам контекста.
Мы печатаем отображаемое имя и идентификатор контекста приложения.
Мы получаем MyBean из фабрики компонентов, используя метод getBean(). Затем мы вызываем его метод getApplicationId().
Мы запускаем приложение с помощью gradlew -q bootRun. Из вывода видно, что мы используем AnnotationConfigApplicationContext .
В этом руководстве мы представим Spring Boot ApplicationContext .
Источник
Приложение Spring Контекст
Последнее изменение: 11 февраля 2022 г.
В своей работе мы полагаемся на чужой код . Повседневная. Это может быть язык, на котором вы пишете, структура, на которой вы работаете, или какое-то эзотерическое программное обеспечение, которое делает что-то настолько хорошо, что вы никогда не чувствовали необходимости реализовывать его самостоятельно.
Проблема, конечно, когда вещи в производстве ломаются: отладка реализации сторонней библиотеки, о которой у вас нет глубоких знаний, по меньшей мере сложна. Трудно понять, что с чем связано и какая именно часть основной библиотеки неисправна.
Lightrun — это новый тип отладчика.
Он специально предназначен для реальных производственных сред. С помощью Lightrun вы можете детализировать запущенные приложения, включая сторонние зависимости, с помощью журналов, снимков и метрик в реальном времени. Никаких исправлений, повторных дистрибутивов или перезагрузки не требуется.
Узнайте больше в этом кратком 5-минутном учебном пособии по Lightrun:
Начните работу с Spring 5 и Spring Boot 2 с помощью справочного курса Изучите Spring :
1. Обзор
В этом руководстве мы подробно рассмотрим интерфейс Spring ApplicationContext .
Дополнительная литература:
Данные Spring JPA @Query
Spring Boot Error ApplicationContextException
Ошибка загрузки ApplicationContext для теста JUnit контроллера Spring
2. Интерфейс ApplicationContext
Один раз одной из основных функций фреймворка Spring является контейнер IoC (Inversion of Control). Контейнер Spring IoC отвечает за управление объектами приложения. Он использует внедрение зависимостей для достижения инверсии управления.
Интерфейсы BeanFactory и ApplicationContext представляют контейнер Spring IoC . Здесь BeanFactory — это корневой интерфейс для доступа к контейнеру Spring. Он обеспечивает основные функции управления bean-компонентами.
С другой стороны, ApplicationContext является субинтерфейсом BeanFactory . Поэтому он предлагает все функции BeanFactory.
Кроме того, предоставляет дополнительные функции для конкретных компаний . Важными функциями ApplicationContext являются разрешение сообщений , поддержка интернационализации, публикация событий и контексты уровня приложений . Поэтому мы используем его в качестве контейнера Spring по умолчанию.
3. Что такое bean-компонент Spring?
Прежде чем погрузиться в контейнер ApplicationContext , важно знать о Весенняя фасоль. В Spring bean-компонент — это объект, который контейнер Spring создает, компилирует и управляет .
Итак, должны ли мы настраивать все объекты в нашем приложении как bean-компоненты Spring? Что ж, лучше не делать этого.
Согласно документации Spring, как правило, мы должны определять bean-компоненты для объектов сервисного уровня, объектов доступа к данным (DAO), объектов представления, объектов инфраструктуры, таких как Hibernate SessionFactories, JMS Queues и т. д.
В общем, нам также не следует настраивать подробные объекты. в контейнерных доменах. Обычно за создание и загрузку объектов предметной области отвечает DAO и бизнес-логика.
Теперь давайте определим простой класс Java, который мы будем использовать в качестве руководства по Spring Bean:
4. Настройка бинов в контейнере
Как мы знаем, основная задача ApplicationContext состоит в управлении бинами.
Таким образом, приложение должно предоставлять объект bean-компонента конфигурации контейнера ApplicationContext . Конфигурация bean-компонента Spring состоит из одного или нескольких определений bean-компонентов. Spring также поддерживает различные способы настройки bean-компонентов.
4.1. Конфигурация на основе Java
Во-первых, мы начнем с конфигурации на основе Java, поскольку это самый последний и наиболее предпочтительный способ настройки bean-компонентов. Он доступен, начиная с Spring 3.0 и выше. Аннотация @Bean к методу указывает, что метод создает компонент Spring. Кроме того, класс с аннотацией @Configuration означает, что он содержит конфигурации Spring Bean.
Теперь мы создаем класс конфигурации, который определяет наш класс AccountService как Spring Bean:
4.2. Конфигурация на основе аннотаций
В Spring 2.5 появилась конфигурация Настройка на основе аннотаций в качестве первого шага к включению конфигураций bean-компонентов в Java.
В этом подходе мы сначала включаем настройку на основе аннотаций через XML-конфигурацию. Затем мы используем набор аннотаций для наших классов, методов, конструкторов или полей. Java для настройки bean-компонентов. Некоторые примеры этих аннотаций: @Component , @Controller , @Service , @Repository , @Autowired и @Qualifier .
В основном мы используем эти аннотации также с конфигурацией на основе Java. Стоит также отметить, что с каждым выпуском Spring продолжает добавлять дополнительные параметры к этим аннотациям.
Теперь давайте рассмотрим простой пример этой конфигурации.
Сначала мы создадим XML-конфигурацию. , пользователь — bean-config.xml для включения аннотаций:
Здесь тег annotation-config включает сопоставление на основе аннотаций . Тег component-scan также сообщает Spring, где искать аннотированные классы.
Во-вторых, мы создаем класс UserService и определяем его как компонент Spring с помощью тега @Component :
Затем мы пишем простой тестовый пример для проверки этой конфигурации:
4.3. Конфигурация на основе XML
Наконец, давайте рассмотрим конфигурацию на основе XML. Это традиционный способ настройки bean-компонентов в Spring.
При таком подходе, конечно, мы делаем сопоставление всех bean-компонентов в файле конфигурации XML .
Итак, давайте создадим Файл конфигурации XML, account-bean-config.xml и определить компоненты для нашего класса AccountService :
5. Типы Контекст приложения
Spring предоставляет различные типы контейнеров ApplicationContext , подходящие для различных требований. Это реализации интерфейса ApplicationContext . Итак, давайте рассмотрим некоторые распространенные типы ApplicationContext .
5.1. AnnotationConfigApplicationContext
Во-первых, давайте рассмотрим класс AnnotationConfigApplicationContext , который был представлен в Spring 3.0. Вы можете использовать классы с аннотациями @Configuration , @Component , и JSR-330 в качестве входных данных.
Затем давайте рассмотрим простой пример использования оболочки AnnotationConfigApplicationContext с нашей конфигурацией на основе Java:
5.2. AnnotationConfigWebApplicationContext
Мы можем использовать этот класс при настройке прослушивателя сервлетов Spring ContextLoaderListener или Spring MVC DispatcherServlet в Интернете . xml .
Начиная с Spring 3.0, мы также можем настраивать эту оболочку контекста приложения программно. Все, что нам нужно сделать, это реализовать интерфейс WebApplicationInitializer :
5.3. XmlWebApplicationContext
Если мы используем конфигурацию на основе XML в веб-приложении , мы можем использовать класс XmlWebApplicationContext .
Из сделанного, настроить эту оболочку похоже только на класс AnnotationConfigWebApplicationContext , что означает, что мы можем настроить ее в web.xml, или реализовать интерфейс WebApplicationInitializer :
5.4 . XML-контекст приложения файловой системы
Мы используем класс FileSystemXMLApplicationContext для загрузки файла конфигурации Spring на основе XML из файловой системы или из URL. Этот класс полезен, когда нам нужно программно загрузить ApplicationContext . Как правило, наборы тестов и автономные приложения являются одними из возможных вариантов использования.
Например, давайте посмотрим, как мы можем создать этот контейнер Spring и загрузить компоненты для нашей конфигурации на основе XML:
5,5. Контекст приложения ClassPathXml
Если мы хотим загрузить файл конфигурации XML из пути к классу , мы можем использовать класс ClassPathXmlApplicationContext . Подобно FileSystemXMLApplicationContext, полезен для тестирования пакетов, а также контекстов приложений, встроенных в файлы JAR.
Итак, давайте рассмотрим пример использования этого класса:
6 Еще особенности ApplicationContext
6.1. Интерфейс разрешения сообщений
ApplicationContext поддерживает разрешение сообщений и интернационализацию при расширении интерфейса MessageSource . Кроме того, Spring предоставляет две реализации MessageSource. , ResourceBundleMessageSource и StaticMessageSource .
Чтобы добавить сообщения, мы можем использовать StaticMessageSource к ресурсу программно; однако он поддерживает базовую интернационализацию и больше подходит для тестирования, чем для производства.
С другой стороны, ResourceBundleMessageSource является наиболее распространенной реализацией MessageSource . Он основан на реализации ResouceBundle базового JDK. Он также использует стандартный анализ сообщений JDK, предоставляемый MessageFormat .
Теперь давайте посмотрим, как мы можем использовать MessageSource для чтения сообщений из файла свойств.
Сначала мы создаем файл messages.properties в пути к классам:
Во-вторых, мы добавляем определение компонента в наш класс AccountConfig :
Третий , мы вставляем MessageSource в AccountService :
Наконец, мы можем использовать метод getMessage в любом месте AccountService для чтения сообщение:
Spring также предоставляет класс ReloadableResourceBundleMessageSource , который позволяет считывать файлы из любого местоположения ресурса Spring и поддерживает быструю перезагрузку файлов свойств пакета.
6.2. Управление событиями
ApplicationContext поддерживает обработку событий с использованием класса ApplicationEvent и интерфейса ApplicationListener . Поддерживает встроенные события, такие как ContextStartedEvent , ContextStoppedEvent , ContextClosedEvent и RequestHandledEvent . Кроме того, он также поддерживает пользовательские события для бизнес-применений.
7. Заключение
В этой статье мы обсудим различные аспекты контейнера ApplicationContext в Spring. Мы также рассмотрим различные примеры настройки компонентов Spring в ApplicationContext . Наконец, мы научились создавать и использовать различные типы ApplicationContext .
Как всегда, весь код доступен на GitHub.
Источник
Spring: в поисках контекста
Текстовые сообщения находятся в журнале поиска JVM. После этой презентации мои коллеги задали хороший вопрос: какой механизм использует Spring для анализа конфигураций и как он загружает классы из контекста?
спустя много часов отладки
Теория истории
сраз оре амайтар приложение.
Прежде чем перейти непосредственно к демонстрации, давайте рассмотрим шаги, связанные с созданием ApplicationContext :
В этом посте мы рассмотрим первую фазу, потому что нам интересно прочитать конфигурацию и создать BeanDefinition.
BeanDefinition — это интерфейс, описывающий компонент, его свойства, аргументы построения и другую метаинформацию.
Когда дело доходит до настройки самих bean-компонентов, Spring имеет 4 варианта конфигурации:
- Конфигурация XML — ClassPathXmlApplicationContext(”context.xml” ) ;
- Настройки Groovy — GenericGroovyApplicationContext(”context.groovy”);
- Конфигурация с использованием аннотаций, указывающих проверяемый пакет — AnnotationConfigApplicationContext(”package.name”);
- JavaConfig : конфигурация с использованием аннотаций, указывающих класс (или массив классов), снабженный аннотацией @Configuration: AnnotationConfigApplicationContext(JavaConfig.class).
Конфигурация XML
За основу возьмем простой проект:
Здесь необходимо немного пояснить, что используются методы и почему для какой цели:
- printLoadedClasses(String… фильтры) : метод отображает имя загрузчика и классы JVM, загруженные из пакета, переданного как параметр в консоль. Кроме того, есть информация о количестве всех загруженных классов;
- doSomething(Object o) — метод, выполняющий некоторую примитивную работу, но не позволяющий исключить упомянутые классы при оптимизации процесса компиляции.
Подключаемся к проекту Spring (отныне Spring 4 действует как тестовый пример):
Строка 25 объявляет и инициализирует ApplicationContext через конфигурацию XML .
Файл конфигурации XML выглядит следующим образом:
Укажите фактический класс при настройке компонента. Обратите внимание на набор свойств lazy-init=»true» : в этом случае бин будет создаваться только по запросу из контекста.
Мы видим, как Spring разрешается при загрузке контекста ситуация с классами, объявленными в конфигурационном файле:
Рассмотрим детали конфигурации Xml:
: Конфигурационный файл читается классом XmlBeanDefinitionReader , который реализует интерфейс BeanDefinitionReader ;
— XmlBeanDefinitionReader принимает InputStream в качестве входных данных и загружает Document через DefaultDocumentLoader :
— Затем каждый элемент этого документа обрабатывается и, если это bean-компонент, создается BeanDefinition на основе заполненных данных (id, имя, класс, псевдоним, метод запуска, метод уничтожения и т. д.):
— Каждое определение BeanDefinition помещается в карту, хранящуюся в классе DefaultListableBeanFactory:
В коде карта выглядит следующим образом:
Теперь в том же файле конфигурации, добавим еще одно объявление компонента с классом movie .BadVillain :
Посмотрим, что произойдет, когда мы напечатаем сгенерированный список BeanDefenitionNames и загрузим классы:
И хотя класс movie.BadVillain указанный в конфигурационном файле не существует, Spring обрабатывает без ошибок:
List BeanDefenitionNames содержит 2 элемента; это означает, что эти 2
BeanDefinitions, сконфигурированные в нашем файле, были созданы.
Конфигурации обоих bean-компонентов практически одинаковы. Но при загрузке существующего класса проблем не возникло. Из чего можно сделать вывод, что тоже была попытка загрузки несуществующий класс, но неудачная попытка ничего не сломала.
Попробуем получить bean-компоненты по их именам:
Если в первом случае был получен допустимый bean-компонент, во втором случае было сгенерировано исключение .
Обратите внимание на трассировку стека: сработала ленивая загрузка классов. Перебрать все загрузчики классов, пытаясь найти нужный класс среди ранее загруженных. А после того, как нужный класс не был найден, вызов метода Utils.forName пытался найти несуществующий класс по имени, что приводило к естественной ошибке.
При генерации контекста был загружен только один класс, при этом попытка загрузки несуществующего файла не привела к ошибке. Почему так случилось?
Вот почему мы написали lazy-init:true и предотвратили создание экземпляра bean-компонента Spring, в котором возникает исключение, пойманное выше. Если вы удалите это свойство из конфигурации или измените его на lazy-init:false , описанная выше ошибка также завершится ошибкой, но не будет проигнорирована и приложение остановится. В нашем случае контекст был инициализирован, но нам не удалось создать экземпляр компонента, поскольку указанный класс не был найден.
Конфигурация Groovy
При настройке контекста с помощью файла Groovy необходимо создать GenericGroovyApplicationContext , который принимает в качестве входных данных строку, содержащую конфигурацию контекста. В этом случае контекст считывается классом GroovyBeanDefinitionReader . Этот параметр работает в основном так же, как Xml, только с файлами Groovy. Также GroovyApplicationContext прекрасно работает с файлом Xml.
Пример простого файла конфигурации Groovy:
Попытка сделать то же самое с XML:
Ан сразу возникает ошибка: Groovy, как и Xml, создает BeanDefenitions, но в этом случае постпроцессор сразу выдает ошибку.
Конфигурация с использованием аннотаций, указывающих пакет для сканирования, или JavaConfig
Эта конфигурация отличается от двух предыдущих. Конфигурация с использованием аннотаций использует 2 варианта: JavaConfig и аннотации классов.
Здесь используется тот же контекст: AnnotationConfigApplicationContext(“package”/JavaConfig.class) . Он работает в зависимости от того, что было передано конструктору.
В контексте AnnotationConfigApplicationContext есть 2 закрытых поля:
- private final AnnotatedBeanDefinitionReader (работает с JavaConfig);
- private end scan ClassPathBeanDefinitionScanner r (сканирует пакет).
Особенность AnnotatedBeanDefinitionReader в том, что он работает в несколько этапов:
- Регистрация всех файлов @Configuration далее анализ;
- Зарегистрируйте специальный BeanFactoryPostProcessor r, а именно BeanDefinitionRegistryPostProcessor , который использует класс ConfigurationClassParser анализирует JavaConfig и создает BeanDefinition .
Рассмотрим простой пример:
Создайте файл конфигурации с простейшим компонентом. Давайте посмотрим, что он загружает:
В случае Xml и Groovy, если было загружено столько BeanDefinitions, сколько было объявлено, в данном случае во время генерации контекста. При реализации через JavaConfig все классы загружаются во время, включая сам класс JavaConfig, поскольку он является самим компонентом.
Еще один момент: в случае конфигураций Xml и Groovy было загружено 343 файла, а здесь произошла более «сильная» загрузка 631 дополнительного файла.
Этапы задачи ClassPathBeanDefinitionScanner :
- Список файлов для сканирования определяется указанным пакетом. Все файлы заканчиваются каталогами;
- Сканер проверяет каждый файл, принимает InputStream и сканирует с помощью класса org.springframework.asm.ClassReader.class ;
- На третьем этапе сканер проверяет, проходят ли найденные объекты фильтры аннотаций org.springframework.core.type.filter.AnnotationTypeFilter . По умолчанию Spring ищет классы, аннотированные компонентом или любой другой аннотацией, содержащей компонент ;
- Если проверка прошла успешно, создаются и регистрируются новые BeanDefinitions.
Вся «магия» работы с аннотациями, как и в случае с Xml и Groovy, лежит именно в классе ClassReader.class пакета springframework. асм . Особенность этого ридера в том, что он может работать с байт-кодом. То есть читатель получает InputStream байт-кода, сканирует его и ищет в нем аннотации.
Рассмотрим работу сканера на простом примере.
Создайте нашу собственную аннотацию для поиска подходящих классов:
Создайте 2 класса: один со стандартной аннотацией Компонент , один с пользовательской аннотацией:
Результатом является сгенерированное BeanDefinition для этих классов и успешно загруженных классов.
Выход
Исходя из вышеизложенного, на поставленные вопросы можно ответить следующим образом:
- ¿ Какой механизм использует Spring для анализа конфигурации?
Каждая реализация контекста имеет свой набор инструментов, но в основном используется сканирование. Мы не пытаемся загрузить классы перед созданием BeanDefinition: сначала создается сканирование указанных параметров на основе результатов сканирования, а затем создается соответствующее BeanDefinition. Затем постпроцессоры пытаются настроить сам BeanDefinition, загрузить в него класс и так далее. Как пружинная нагрузка вырывается из контекста?
Шрифт