Раздел 3.4.4.5 документации Spring довольно хорошо объясняет это:
(обратите внимание, что следующее определение bean-компонента userPreferences в его нынешнем виде является неполным):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Из приведенной выше конфигурации очевидно, что одноэлементный bean-компонент userManager вводится со ссылкой на HTTP-компонент userPreferences в области сеанса. Важным моментом здесь является то, что bean-компонент userManager является синглтоном ... он будет создан ровно один раз для каждого контейнера , и его зависимости (в данном случае только один bean-компонент userPreferences) также будут введены только (один раз! ) .
Это означает, что «userManager» (концептуально) будет всегда работать только с одним и тем же объектом «userPreferences», то есть с тем, с которым он был изначально введен.
Это не то, что вы хотите, когда вы вставляете bean-компонент с областью действия HTTP в качестве зависимости в сотрудничающий объект (обычно). Скорее, нам действительно нужен один объект userManager для каждого контейнера , а затем, в течение всего времени существования сеанса HTTP, мы хотим видеть и использовать объект userPreferences, специфичный для указанного сеанса HTTP .
Вместо этого вам нужно внедрить какой-то объект, который предоставляет тот же самый открытый интерфейс, что и класс UserPreferences (в идеале объект, который является экземпляром UserPreferences), и который достаточно умен, чтобы иметь возможность уйти и получить реальный объект UserPreferences из любого выбранного механизма определения области видимости (HTTP-запрос, сеанс и т. д.). Затем мы можем безопасно внедрить этот прокси-объект в bean-компонент userManager, который будет блаженно не знать, что ссылка UserPreferences, на которой он держится, является прокси .
В нашем случае, когда экземпляр UserManager вызывает метод в объекте UserPreferences, внедренном зависимостями, он действительно будет вызывать метод на прокси ... затем прокси отключится и получит реальный объект UserPreferences из (в этом случае) HTTP-сеанс и делегируйте вызов метода полученному реальному объекту UserPreferences.
Вот почему вам нужна следующая, правильная и полная конфигурация при внедрении bean-компонентов с областью действия запроса, сеанса и globalSession в взаимодействующие объекты:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>