Spring Framework – первые шаги (Конспект девятый)

Одним из нетривиальных для понимания аспектов в Dependency Injection, является взаимодействие между компонентами с различными зонами видимости. И действительно, если обе компоненты представлены в диапазоне «singleton», взаимодействие между ними достаточно прозрачно: при поднятии контекста приложения создаются экземпляры обеих компонент, существующих на протяжении всего жизненного цикла приложения. Соответственно они всегда доступны друг для друга и имеют возможность взаимодействовать между собой.

Конспект девятый: Dependency Injection компонент с различными scope

Теперь давайте усложним ситуацию и представим себе, что первая компонента описана как singleton, а вторая, как prototype. Кроме этого принимаем во внимание, что «singleton» агрегирует в себе «prototype». Что будет происходить в этом случае?

Здесь важно помнить, что Spring Framework будет создавать новый экземпляр второй компоненты (prototype) каждый раз когда он будет запрашиваться из контекста приложения. Т.о. при создании первой компоненты («singleton»), будет создан и новый экземпляр второй («prototype»). Т.е. если к описанию прототипа будет обращаться еще одна компонента нашего приложения, Spring Framework создаст отдельный экземпляр прототипа и для нее. Это важно не только помнить, но и хорошо понимать.

Давайте рассмотрим все вышесказанное на примере следующего конфигурационного файла:

<beans>
	<bean id="registerFormController"
	class="com.personality.examples.spring.ioc.RegisterFormControllerReadyForIoC">

		<property name="mailService" ref="mailService" />
	</bean>

	<bean id="orderProcessingController"
class="com.personality.examples.spring.ioc.OrderProcessingController">

		<property name="mailService" ref="mailService" />
	</bean>

	<bean id="mailService"
		class="com.personality.examples.spring.ioc.SmtpMailService"
		scope="prototype">
	</bean>
</beans>

Графически такая конфигурация будет выглядеть следующим образом:

IoC singleton-protoype injection example

IoC singleton-protoype injection example

Важно только понимать, что в связи с тем, что mailService описан, как прототип, для registerFormController и для orderProcessingController будут созданы свои экземпляры mailService. При этом важно также понимать, что экземпляры mailService будут создаваться при поднятии контроллеров в контексте приложения. Также важно понимать, что в дальнейшем Spring не будет «заниматься» жизненным циклом каждого из созданных им mailService-ов.

Для того, чтобы перейти к следующей лекции, я предлагаю читателю подумать над такой задачей:

Представьте себе подсистему интернет магазина, которая должна отображать состояние «корзины» в браузере пользователя. Для разработки такой подсистемы мы воспользуемся шаблоном проектирования MVC, представленным графически на рисунке ниже.

MVC Model 2

MVC Model 2

В качестве контроллера в нашей подсистеме будет выступать ShoppingCartShowController, поднятый в контексте приложения как singleton. А в качестве модели, будет выступать компонента ShoppingCart. Основная проблема, над которой должен поразмышлять читатель, заключается в том, что у каждого пользователя своя «корзина» и соответственно, когда «Пользователь 1» посылает запрос на отображение корзины ShoppingCartShowController должен показать ему именно его корзину, а не корзину «Пользователя 145»

Т.о. наш с Вами ShoppingCartShowController должен каким-то образом, при каждом обращении к нему, распознавать пользователя и «подтягивать» из контекста приложения именно его корзину. Так же напомню читателю о том, что Controller должен быть stateless, т.е. не может сохранять состояний между вызовами его методов.

Выход из этой ситуации в следующей раз.

Vyacheslav Yakovenko


This entry was posted in Java, Main menu and tagged . Bookmark the permalink.