Содержание


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

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

Comments

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

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


Ресурсы для скачивания


Похожие темы


Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

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