La sezione 3.4.4.5 dei documenti di primavera lo spiega abbastanza bene:
(si noti che la seguente definizione di bean 'userPreferences' così com'è è incompleta):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Dalla configurazione precedente è evidente che il bean singleton "userManager" viene iniettato con un riferimento al bean con ambito di sessione HTTP "userPreferences". Il punto saliente qui è che il bean 'userManager' è un singleton ... verrà istanziato esattamente una volta per contenitore , e anche le sue dipendenze (in questo caso solo una, il bean 'userPreferences') verranno iniettate solo (una volta! ) .
Ciò significa che "userManager" funzionerà (concettualmente) sempre e solo sullo stesso identico oggetto "userPreferences", ovvero quello con cui è stato originariamente iniettato.
Questo non è ciò che si desidera quando si inietta un bean con ambito di sessione HTTP come dipendenza in un oggetto collaborante (in genere). Piuttosto, quello che vogliamo è un singolo oggetto "userManager" per contenitore , quindi, per la durata di una sessione HTTP, vogliamo vedere e utilizzare un oggetto "userPreferences" specifico per detta sessione HTTP .
Piuttosto ciò di cui hai bisogno è iniettare una sorta di oggetto che esponga la stessa identica interfaccia pubblica della classe UserPreferences (idealmente un oggetto che è un'istanza di UserPreferences) e che sia abbastanza intelligente da essere in grado di andare a prendere il vero oggetto UserPreferences da qualsiasi meccanismo di scoping sottostante che abbiamo scelto (richiesta HTTP, sessione, ecc.). Possiamo quindi iniettare in modo sicuro questo oggetto proxy nel bean "userManager", che sarà beatamente inconsapevole che il riferimento UserPreferences a cui si tiene è un proxy .
Nel nostro caso, quando un'istanza di UserManager richiama un metodo sull'oggetto UserPreferences inserito nella dipendenza, invocerà davvero un metodo sul proxy ... il proxy si spegnerà e recupererà l'oggetto UserPreferences reale da (in questo caso) la sessione HTTP e delegare la chiamata al metodo sull'oggetto UserPreferences reale recuperato.
Questo è il motivo per cui è necessaria la seguente configurazione, corretta e completa, quando si inseriscono bean con ambito di richiesta, sessione e globalSession negli oggetti collaboranti:
<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>