musim semi kacang proxy yang dicakup

98

Adakah yang bisa menjelaskan penggunaan @ScopedProxyanotasi pegas ? Saya pikir itu ada hubungannya dengan sesi kacang bercakupan, tapi saya tidak begitu yakin apa.

Dalam penggunaan cakupan, saya telah menggunakan kacang cakupan sesi tanpa @ScopedProxyanotasi (atau tanpa proksi cakupan aop), jadi saya benar-benar yakin bagaimana menggunakannya dengan benar.

Jeff Storey
sumber
lihat dokumentasi kacang . Sesi adalah salah satu cakupannya , tetapi bukan satu-satunya.
Gus
1
@Gus, saya mengetahui cakupannya, hanya saja tidak yakin bagaimana proxy cakupan berperan dalam hal itu
Jeff Storey
1
Bagian 3.4.4.5 menurut saya adalah penjelasan yang cukup bagus tentang apa yang dilakukan oleh scoped proxy. - bit di antara dua contoh adalah bagian penting.
Gus
2
Ya itu menjelaskannya, terima kasih. Jika Anda ingin menambahkan jawaban untuk pertanyaan saya akan menerima.
Jeff Storey

Jawaban:

248

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>
Gus
sumber
Jadi, saat saya menggunakan anotasi @ScopedProxy, Proxy akan digunakan secara otomatis, dan ini semua? ScopedProxy artinya -> Jangan gunakan kelas ini sebagaimana adanya, gunakan Proxy untuk itu?
Koray Tugay
3
Saya menggunakan spring-web: 4.3.3 dan sepertinya anotasi @ScopedProxydiganti dengan @RequestScopedan lainnya. Anda dapat menemukan contohnya di sini: logicbig.com/tutorials/spring-framework/spring-core/…
adebasi
1
Bisa dibilang ketika notasi @Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)digunakan, SpringMVC tidak menggunakan WebApplicationContext for Autowired, melainkan menggunakan CGLIB untuk membuat proxy ?. Berikut penjelasan lain dengan contoh-contoh keluar
Kurapika
0

Setelah mencoba berbagai opsi berbeda yang ditentukan di sini dan dokumentasi musim semi, saya telah menemukan untuk beberapa alasan Spring MVC, adalah pengontrol autowiring yang aneh ketika Anda menggunakan anotasi @Controller dan di mana Anda memiliki lebih dari satu pengontrol seperti itu di aplikasi web Anda. Mengubah anotasi menjadi @RestController (value = "UniqueControllerv1"), masalah telah teratasi.

geeksquad87
sumber