La sección 3.4.4.5 de los documentos de primavera lo explica bastante bien:
(tenga en cuenta que la siguiente definición de bean 'userPreferences' tal 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 de la configuración anterior, es evidente que el bean singleton 'userManager' se está inyectando con una referencia al bean de ámbito de sesión HTTP 'userPreferences'. El punto destacado aquí es que el bean 'userManager' es un singleton ... se instanciará exactamente una vez por contenedor , y sus dependencias (en este caso solo una, el bean 'userPreferences') también solo se inyectarán (¡una vez! ) .
Esto significa que el 'userManager' (conceptualmente) solo operará en el mismo objeto 'userPreferences', que es el que se inyectó originalmente.
Esto no es lo que desea cuando inyecta un bean de ámbito de sesión HTTP como una dependencia en un objeto colaborador (normalmente). Más bien, lo que queremos es un único objeto 'userManager' por contenedor , y luego, durante la vida útil de una sesión HTTP, queremos ver y usar un objeto 'userPreferences' que sea específico de dicha sesión HTTP .
Más bien, lo que necesita es inyectar algún tipo de objeto que exponga exactamente la misma interfaz pública que la clase UserPreferences (idealmente un objeto que sea una instancia de UserPreferences) y que sea lo suficientemente inteligente como para poder ir y buscar el objeto UserPreferences real desde cualquier mecanismo de alcance subyacente que hayamos elegido (solicitud HTTP, sesión, etc.). Luego podemos inyectar de manera segura este objeto proxy en el bean 'userManager', que ignorará felizmente que la referencia de UserPreferences que está sosteniendo es un proxy .
En nuestro caso, cuando una instancia de UserManager invoca un método en el objeto UserPreferences inyectado en dependencia, realmente invocará un método en el proxy ... el proxy se apagará y buscará el objeto UserPreferences real de (en este caso) la sesión HTTP y delegar la invocación del método en el objeto UserPreferences real recuperado.
Es por eso que necesita la siguiente configuración, correcta y completa, al inyectar beans con ámbito de solicitud, sesión y sesión global en objetos de colaboración:
<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>