Содержание
- Введение
- Общие сведения
- Введение в аннотации @Configuration и @Bean
- Регистрация класса конфигурации с помощью AnnotationConfigApplicationContext
- Конфигурирование приложения
- Реализация обратных вызовов для извещения о событиях жизненного цикла и области действия bean-компонента
- Ресурсы для скачивания
- Похожие темы
- Комментарии
Управление bean-компонентами Spring при конфигурировании на основе Java
Узнайте, как осуществлять управление bean-компонентами Spring при конфигурировании на основе Java
Общие сведения
Как вы знаете, среда Spring реализует и продвигает принцип инверсии управления (IOC) или внедрения зависимости (DI) и является по сути IOC-контейнером. Традиционно Spring позволяет разработчику осуществлять управление зависимостями bean-компонентов с помощью конфигурирования на основе XML путем использования XML-файла контекста приложения. Этот файл является внешним для приложения, и в нем содержатся определения bean-компонентов и их зависимостей для этого приложения. Несмотря на то, что подход с использованием XML-конфигурирования прост и удобен, существует и альтернативный способ, с помощью которого можно определять bean-компоненты и их зависимости. Этот способ – конфигурирование на основе Java. В отличие от XML-подхода, конфигурирование на основе Java позволяет осуществлять управление bean-компонентами программными средствами. С этой целью применяются различные аннотации. В данной статье мы сравним Java-конфигурирование и традиционный подход к конфигурированию на основе XML, что позволит разработчику лучше понять суть дела. В статье описаны основы Java-конфигурирования и рассмотрены следующие темы:
- Введение в аннотации @Configuration и @Bean
- Регистрация класса конфигурации с помощью AnnotationConfigApplicationContext
- Конфигурирование Web-приложения
- Реализация методов обратного вызова (callback) для извещения о событиях жизненного цикла и область действия bean-компонента
В качестве примера мы рассмотрим сценарий создания курса (Create Course) для некоторого онлайн-университета. В процессе создания курса вы также формируете тематические разделы или модули, при этом каждый тематический раздел может иметь различные назначения. Таким образом, мы создаем три bean-компонента: Course (Курс), Module (Модуль) и Assignment (Назначение). Bean-компонент Course
будет ссылаться на bean-компонент Module
, который, в свою очередь, будет иметь ссылку на bean-компонент Assignment
.
Введение в аннотации @Configuration и @Bean
В идеале вы бы определили bean-компоненты в XML-файле, который содержит конфигурацию контекста приложения. Нижеследующий программный код показывает XML-файл контекста приложения с определениями bean-компонентов для сценария create course:
Листинг 1. XML-файл с определениями bean-компонентов
<beans> <bean id="course" class="demo.Course"> <property name="module" ref="module"/> </bean> <bean id="module" class="demo.Module"> <property name="assignment" ref="assignment"/> </bean> <bean id="assignment" class="demo.Assignment" /> </beans>
Представленный выше XML-файл — это то, что вы обычно пишете для конфигурирования bean-компонентов в среде разработки Spring. Данный XML-файл определяет bean-компонент Course
, который ссылается на bean-компонент Module
, а bean-компонент Module
ссылается на bean-компонент Assignment
. Давайте отставим в сторону этот XML-файл и напишем вместо него эквивалентный программный код Java. Мы определим указанные выше bean-компоненты с использованием конфигурирования на основе Java. XML-файл мы заменим классом Java, который теперь будет играть роль платформы для конфигурирования bean-компонентов. Назовем этот класс AppContext.java
. Следующий фрагмент кода показывает класс AppContext
.
Листинг 2. Класс конфигурации AppContext, содержащий определения bean-компонентов
@Configuration public class AppContext { @Bean public Course course() { Course course = new Course(); course.setModule(module()); return course; } @Bean public Module module() { Module module = new Module(); module.setAssignment(assignment()); return module; } @Bean public Assignment assignment() { return new Assignment(); } }
Как видно из приведенного выше программного кода, теперь bean-компоненты определены программными средствами в рамках конфигурирования на основе Java. Теперь класс AppContext
представляет собой класс конфигурации, совсем как XML-файл. Это достигается путем использования аннотации @Configuration
, которая размещается над классом. Она сообщает контейнеру Spring, что это класс конфигурации, содержащий определения и зависимости bean-компонентов. Для определения bean-компонентов используется аннотация @Bean
. Данная аннотация размещается над методом, который создает экземпляр bean-компонента и устанавливает зависимость. По умолчанию имя этого метода совпадает с идентификатором или именем bean-компонента. В результате вызова метода возвращается bean-компонент, зарегистрированный в контексте приложения Spring. Для установления зависимостей используются методы setter bean-компонента, и контейнер будет вызывать их для «прокладки» связей. Конфигурирование на основе Java также можно рассматривать как конфигурирование на основе аннотаций.
Регистрация класса конфигурации с помощью AnnotationConfigApplicationContext
В традиционном XML-подходе для загрузки внешнего XML-файла контекста приложения вы использовали бы класс ClassPathXmlApplicationContext
. Однако при конфигурировании на основе Java у нас имеется класс AnnotationConfigApplicationContext
. Класс AnnotationConfigApplicationContext
является реализацией интерфейса ApplicationContext
, которая позволяет регистрировать аннотированные классы конфигурации. В данном случае классом конфигурации является класс AppContext
, объявленный с помощью аннотации @Configuration
. После того как вы зарегистрируете указанный класс, также регистрируются все типы bean-компонентов, возвращаемые с помощью методов, которые аннотируются с помощью @Bean
. Нижеследующий фрагмент программного кода показывает пример использования класса AnnotationConfigApplicationContext
:
Листинг 3. Регистрация класса AppContext с помощью AnnotationConfigApplicationContext
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class); Course course = ctx.getBean(Course.class); course.getName(); }
Как видно из приведенного выше программного кода, регистрация класса конфигурации AppContext
осуществляется путем его передачи в конструктор AnnotationConfigApplicationContext
. В качестве альтернативы для регистрации класса конфигурации вы также можете использовать метод register
указанного класса контекста. Этот альтернативный способ показан в нижеследующем фрагменте программного кода.
Листинг 4. Регистрация класса AppContext: альтернативный способ
public static void main(String[] args) { ApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AppContext.class) }
При регистрации класса конфигурации автоматически регистрируются имена методов, аннотированных с помощью @Bean
, и, следовательно, соответствующие bean-компоненты, т. е. Course
, Module
и Assignment
. После этого можно использовать метод getBean
для извлечения соответствующего bean-компонента и вызова его бизнес-методов. Как вы видите, создать класс конфигурации на основе Java и зарегистрировать его в контексте Spring очень просто. В следующем разделе мы обсудим конфигурирование на основе Java применительно к Web-приложению.
Конфигурирование приложения
Обычно конфигурирование Web-приложений Spring осуществляется с использованием контекста XmlWebApplicationContext
путем указания пути к внешнему XML-файлу контекста в файле дескриптора Web-развертывания web.xml. По умолчанию Web-приложение использует класс контекста XMLWebApplicationContext
. В нижеследующем фрагменте программного кода в файле web.xml
показан элемент, указывающий на внешний XML-файл контекста приложения, который будет загружаться прослушивающим классом ContextLoaderListener
.
Листинг 5. Использование внешнего XML-файла контекста приложения в web.xml
<web-app> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>sampleServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> </servlet> ... </web-app>
Теперь мы изменим приведенный выше программный код в файле web.xml
для применения класса AnnotationConfigApplicationContext
. Напомню, что XmlWebApplicationContext
— это установленная по умолчанию реализация контекста, используемая средой Spring для Web-приложений, и поэтому данный класс контекста никогда явным образом не указывается в файле web.xml. Поскольку вы будете конфигурировать на основе Java, вам потребуется указать класс AnnotationConfigApplicationContext
в своем файле web.xml
при его конфигурировании для Web-приложения. Приведенный выше программный код теперь должен выглядеть следующим образом:
Листинг 6. Измененный файл web.xml, в котором используется класс AnnotationConfigApplicationContext
<web-app> <context-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context. support.AnnotationConfigWebApplicationContext </param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value> demo.AppContext </param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <servlet> <servlet-name>sampleServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextClass</param-name> <param-value> org.springframework.web.context. support.AnnotationConfigWebApplicationContext </param-value> </init-param> </servlet> ... </web-app>
В приведенном выше измененном файле web.xml
теперь определяется класс контекста AnnotationConfigWebApplicationContext
как часть параметра контекста и элементов сервлета. Местоположение конфигурации контекста теперь указывает на класс конфигурации AppContext
. Это было просто. В следующем разделе будет показана реализация методов обратного вызова для извещения о событиях жизненного цикла и области действия bean-компонента.
Реализация обратных вызовов для извещения о событиях жизненного цикла и области действия bean-компонента
Обратные вызовы для извещения о событиях жизненного цикла
С помощью конфигурирования на основе Java также можно управлять жизненным циклом bean-компонентов. Аннотация @Bean
поддерживает два атрибута (initMethod
и destroyMethod
), которые могут использоваться для определения методов жизненного цикла. Методы жизненного цикла вызываются контейнером при создании экземпляра bean-компонента и перед его уничтожением. Методы жизненного цикла также называются методами обратного вызова, поскольку они вызываются контейнером. Bean-компонент, зарегистрированный с помощью аннотации @Bean
, также поддерживает стандартные аннотации @PostConstruct
и @PreDestroy
как часть JSR-250. Если вы используете для определения bean-компонентов XML-подход, то для определения методов обратного вызова событий жизненного цикла вы будете использовать элемент <bean>. В приведенном ниже фрагменте программного кода показано, как обычно определяются обратные вызовы с использованием элемента <bean> в XML-конфигурации.
Листинг 7. Использование XML-подхода для обратных вызовов событий жизненного цикла
<bean id="course" class="demo.Course" init-method="setup" destroy-method="cleanup" > <property name="module" ref="module"/> </bean>
Нижеследующий фрагмент программного кода показывает порядок использования методов жизненного цикла при конфигурировании на основе Java.
Листинг 8. Реализация методов жизненного цикла bean-компонентов с использованием класса конфигурации AppContext
@Configuration public class AppContext { @Bean(initMethod = "setup", destroyMethod = "cleanup") public Course course() { Course course = new Course(); course.setModule(module()); return course; } @Bean(initMethod = "setup", destroyMethod = "cleanup") public Module module() { Module module = new Module(); module.setAssignment(assignment()); return module; } ... } public class Course { private Module module; private String name; public Course() { } public void setup() { this.name = "M100 Pythagoras Theorems" } public void setModule(Module module) { this.module = module; } public void cleanup() { module = null; } }
В приведенном выше фрагменте программного кода мы снова возвращаемся к классу конфигурации AppContext
. Теперь аннотация @Bean
имеет два дополнительных атрибута: initMethod
и destroyMethod
. Они определяют методы жизненного цикла setup
и cleanup
. Эти методы реализуются в зарегистрированном bean-компоненте и, в конечном счете, вызываются контейнером при инициализации bean-компонента и перед его уничтожением. Bean-компонент Course
, рассматриваемый здесь в качестве примера, иллюстрирует реализацию методов жизненного цикла. Реализованными методами являются setup
и cleanup
. Аналогичным образом эти методы также можно реализовать в bean-компонентах Module
и Assignment
.
Области действия bean-компонентов
Область действия bean-компонента может быть определена с помощью аннотации @Scope
. В XML для этого было принято указывать атрибут области действия в элементе <bean>.
Листинг 9. Использование XML-подхода для определения области действия bean-компонента
<bean id="course" class="demo.Course" scope="prototype" > <property name="module" ref="module"/> </bean>
Нижеследующий фрагмент программного кода показывает порядок определения области действия bean-компонента при конфигурации на основе Java.
Листинг 10. Использование класса конфигурации AppContext для определения области действия bean-компонента
@Configuration public class AppContext { @Bean(initMethod = "setup", destroyMethod = "cleanup") @Scope("prototype") public Course course() { Course course = new Course(); course.setModule(module()); return course; } ... }
Как видно из приведенного выше программного кода, определить область действия bean-компонента в классе конфигурации Java достаточно просто. Указанный выше класс конфигурации AppContext
определяет область действия prototype для bean-компонента Course
с использованием аннотации @Scope
. Область действия по умолчанию —singleton.
Java-конфигурирование позволяет делать множество вещей. В этой статье мы затронули лишь основы. Использование конфигурирования на основе Java не предоставляет никаких существенных преимуществ, это просто альтернатива XML-подходу, предлагаемому средой разработки Spring. Это прекрасный выбор для тех, кто предпочитает не использовать XML в своей среде разработки. Недостатком, разумеется, является то, что при внесении любых изменений в конфигурацию в классе Java вам потребуется перекомпилировать приложение.
Ресурсы для скачивания
Похожие темы
- Оригинал статьи: Spring bean management using Java configuration.
- Разработка Web-сервисов с использованием Apache CXF и Aegis : научитесь разрабатывать Web-сервисы с использованием привязки данных в CXF и Aegis.
- Разработка и реализация Web-сервисов POJO с использованием Spring и Apache CXF, часть 1: Введение в создание Web-сервисов с использованием CXF и Spring.
- Разработка и реализация Web-сервисов POJO с использованием Spring и Apache CXF, часть 2: Создание Web-сервиса RESTful.