|
26-02-2008 Теперь давайте усложним ситуацию и представим себе, что первая компонента описана как singleton, а вторая, как prototype. Кроме этого принимаем во внимание, что «singleton» агрегирует в себе «prototype». Что будет происходить в этом случае?
Конспект девятый: Dependency Injection компонент с различными scope Одним из нетривиальных для понимания аспектов в Dependency Injection, является взаимодействие между компонентами с различными зонами видимости. И действительно, если обе компоненты представлены в диапазоне «singleton», взаимодействие между ними достаточно прозрачно: при поднятии контекста приложения создаются экземпляры обеих компонент, существующих на протяжении всего жизненного цикла приложения. Соответственно они всегда доступны друг для друга и имеют возможность взаимодействовать между собой. Теперь давайте усложним ситуацию и представим себе, что первая компонента описана как 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>
Графически такая конфигурация будет выглядеть следующим образом: 
Важно только понимать, что в связи с тем, что mailService описан, как прототип, для registerFormController и для orderProcessingController будут созданы свои экземпляры mailService. При этом важно также понимать, что экземпляры mailService будут создаваться при поднятии контроллеров в контексте приложения. Также важно понимать, что в дальнейшем Spring не будет «заниматься» жизненным циклом каждого из созданных им mailService-ов. Для того, чтобы перейти к следующей лекции, я предлагаю читателю подумать над такой задачей:
Представьте себе подсистему интернет магазина, которая должна отображать состояние «корзины» в браузере пользователя. Для разработки такой подсистемы мы воспользуемся шаблоном проектирования MVC, представленным графически на рисунке ниже.

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