A seção 3.4.4.5 dos documentos de primavera explica muito bem:
(observe que a seguinte definição de bean 'userPreferences' como está está incompleta):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
A partir da configuração acima, é evidente que o bean singleton 'userManager' está sendo injetado com uma referência ao bean com escopo de sessão HTTP 'userPreferences'. O ponto saliente aqui é que o bean 'userManager' é um singleton ... ele será instanciado exatamente uma vez por contêiner , e suas dependências (neste caso apenas um, o bean 'userPreferences') também serão injetadas (uma vez! ) .
Isso significa que o 'userManager' irá (conceitualmente) operar apenas no mesmo objeto 'userPreferences', que é aquele com o qual foi originalmente injetado.
Isso não é o que você quer quando injeta um bean com escopo de sessão HTTP como uma dependência em um objeto de colaboração (normalmente). Em vez disso, o que queremos é um único objeto 'userManager' por contêiner e, então, durante o tempo de vida de uma Sessão HTTP, queremos ver e usar um objeto 'userPreferences' específico para a referida Sessão HTTP .
Em vez disso, o que você precisa é injetar algum tipo de objeto que exponha exatamente a mesma interface pública que a classe UserPreferences (de preferência um objeto que seja uma instância de UserPreferences) e que seja inteligente o suficiente para poder ir buscar o objeto UserPreferences real de qualquer mecanismo de escopo subjacente que escolhemos (solicitação HTTP, sessão, etc.). Podemos então injetar com segurança esse objeto proxy no bean 'userManager', que felizmente não perceberá que a referência UserPreferences que está segurando é um proxy .
Em nosso caso, quando uma instância do UserManager invoca um método no objeto UserPreferences injetado por dependência, ela realmente invoca um método no proxy ... o proxy então dispara e busca o objeto UserPreferences real (neste caso) a Sessão HTTP e delegar a invocação do método ao objeto UserPreferences real recuperado.
É por isso que você precisa da seguinte configuração correta e completa ao injetar beans com escopo request-, session- e globalSession em objetos de colaboração:
<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>