Управление bean-компонентами Spring при конфигурировании на основе Java

Узнайте, как осуществлять управление bean-компонентами Spring при конфигурировании на основе Java

Обычно bean-компоненты Spring конфигурируются с использованием традиционного XML-подхода. Из этой статьи вы узнаете, как создавать bean-компоненты Spring и конфигурировать их с применением конфигурирования исключительно на основе Java вместо применения XML. В статье рассматриваются различные аннотации, которые можно использовать для конфигурирования bean-компонента, а также сравниваются конфигурирование на основе Java и традиционный подход на основе XML.

Раджив Хатхи, архитектор Java, Свободный писатель

Rajeev HathiРаджив Хатхи (Rajeev Hathi) работает консультантом по программному обеспечению для платформы J2EE. Его профессиональными интересами являются создание архитектурных решений, проектирование и разработка приложений на основе J2EE. Раджив имеет сертификаты SUN в области технологий Java и J2EE (Core Java, Web, EJB, архитектура). Он подготовил несколько технических материалов для портала IBM developerWorks. Кроме того, Раджив является соавтором книги “Apache CXF Web Service Development” (Разработка Web-сервисов Apache CXF). В свободное время он любит слушать музыку и смотреть спортивные состязания. Официальный Web-сайт автора находится по адресу http://www.rajeevhathi.com и представляет собой технический блог. Связаться с автором можно по адресу электронной почты rajeevhathi@gmail.com.



31.10.2012

Общие сведения

Как вы знаете, среда 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 вам потребуется перекомпилировать приложение.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=SOA и web-сервисы
ArticleID=843742
ArticleTitle=Управление bean-компонентами Spring при конфигурировании на основе Java
publish-date=10312012