Bagian 3.4.4.5 dari dokumen musim semi menjelaskannya dengan cukup baik:
(harap dicatat bahwa definisi kacang 'userPreferences' berikut ini tidak lengkap):
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
<bean id="userManager" class="com.foo.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Dari konfigurasi di atas, terbukti bahwa kacang tunggal 'userManager' sedang diinjeksi dengan referensi ke kacang 'userPreferences' dengan cakupan Sesi HTTP. Poin penting di sini adalah bahwa kacang 'userManager' adalah tunggal ... itu akan dibuat persis sekali per kontainer , dan ketergantungannya (dalam hal ini hanya satu, kacang 'userPreferences') juga hanya akan disuntikkan (sekali! ) .
Ini berarti bahwa 'userManager' (secara konseptual) hanya akan beroperasi pada objek 'userPreferences' yang sama persis, yaitu objek yang pertama kali digunakan.
Ini bukan yang Anda inginkan ketika Anda memasukkan kacang bercakupan Sesi HTTP sebagai dependensi ke dalam objek yang berkolaborasi (biasanya). Sebaliknya, yang kami inginkan adalah satu objek 'userManager' per kontainer , dan kemudian, selama Sesi HTTP, kami ingin melihat dan menggunakan objek 'userPreferences' yang dikhususkan untuk Sesi HTTP tersebut .
Alih-alih apa yang Anda butuhkan kemudian adalah menyuntikkan semacam objek yang mengekspos antarmuka publik yang sama persis dengan kelas UserPreferences (idealnya sebuah objek yang merupakan instance UserPreferences) dan itu cukup pintar untuk dapat pergi dan mengambil objek UserPreferences yang sebenarnya dari mekanisme pelingkupan apa pun yang mendasari yang telah kami pilih (permintaan HTTP, Sesi, dll.). Kami kemudian dapat dengan aman menyuntikkan objek proxy ini ke dalam kacang 'userManager', yang akan dengan senang hati tidak menyadari bahwa referensi UserPreferences yang dipegangnya adalah proxy .
Dalam kasus kami, ketika instance UserManager memanggil metode pada objek UserPreferences yang diinjeksi dependensi, itu benar-benar akan memanggil metode pada proxy ... proxy kemudian akan pergi dan mengambil objek UserPreferences yang sebenarnya dari (dalam kasus ini) Sesi HTTP, dan mendelegasikan pemanggilan metode ke objek UserPreferences asli yang diambil.
Itulah mengapa Anda memerlukan konfigurasi berikut, benar dan lengkap saat memasukkan kacang bercakupan permintaan, sesi, dan globalSession ke dalam objek yang berkolaborasi:
<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>