весняний обшитий проксі-боб


98

Чи може хтось пояснити використання весняної @ScopedProxyанотації? Я подумав, що це пов'язане з квасолею, але я не зовсім впевнений, що.

У своєму використанні областей я використовував квасолі з сеансами без @ScopedProxyпримітки (або без проксі-сервісів), тому я справді впевнений, як правильно її використовувати.


перевірити документацію на квасоля . Сесія - одна з областей , але не єдина.
Гас

1
@Gus, я знаю про сфери, просто не впевнений, як грає проксі-проксі
Jeff Storey

1
Розділ 3.4.4.5 , на мій погляд, є досить хорошим поясненням того, що робить проксі-сервер. - біт між двома прикладами є важливою частиною.
Гас

2
Так, це пояснює, дякую. Якщо ви хочете додати відповідь на питання, я прийму.
Джефф Сторі

Відповіді:


248

Розділ 3.4.4.5 весняних документів досить добре пояснює:

(будь ласка, зауважте, що наведене нижче визначення "beanPreferences" є неповним):

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

<bean id="userManager" class="com.foo.UserManager">
    <property name="userPreferences" ref="userPreferences"/>
</bean>

З вищенаведеної конфігурації видно, що однотонному "userManager" вводиться посилання на HTTP-сеанс "userPreferences". Важливим моментом тут є те, що «userManager» bean є однотонним ... він буде інстанціюватися рівно один раз на контейнер , а його залежності (у цьому випадку лише одна, «userPreferences») також будуть введені лише один раз (один раз! ) .

Це означає, що "userManager" (концептуально) працюватиме лише колись із таким самим об'єктом "userPreferences", тобто тим, в який він був спочатку введений.

Це не те, що ви хочете, коли ви вводите об'єкт HTTP-сеансу як залежність в об'єкт, що співпрацює (як правило). Швидше, що ми хочемо - це один об'єкт "userManager" на контейнер , і тоді, протягом усього сеансу HTTP, ми хочемо побачити та використовувати об'єкт "userPreferences", який є специфічним для зазначеного HTTP-сесії .

Швидше за все, що вам потрібно - це ввести якийсь об'єкт, який відкриває такий самий публічний інтерфейс, що і клас UserPreferences (в ідеалі - це об'єкт, який є примірником UserPreferences), і який досить розумний, щоб можна було вийти з нього та отримати реальний об'єкт UserPreferences. з будь-якого базового механізму обстеження, який ми обрали (HTTP-запит, сесія тощо). Тоді ми можемо безпечно вводити цей проксі-об’єкт у поле "userManager", яке буде невідомо, що посилання UserPreferences, на які він утримує, - це проксі .

У нашому випадку, коли екземпляр UserManager викликає метод на об'єкті UserPreferences, який вводить залежність, він дійсно буде викликати метод на проксі-сервері ... проксі-сервер вимкнеться та отримає реальний об'єкт UserPreferences (у цьому випадку) сеанс HTTP і делегуйте виклик методу на отриманий реальний об'єкт UserPreferences.

Ось чому вам потрібна наступна, правильна та повна конфігурація при введенні бобів, що охоплюють запит, сеанс та глобальну сесію, в об'єкти, що співпрацюють:

<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>

Отже, коли я використовую анотацію @ScopedProxy, автоматично використовуватиметься проксі, і це все? ScopedProxy означає -> Не використовувати цей клас таким, який він є, використовувати для нього проксі?
Корай Тугай

3
Я використовую spring-web: 4.3.3, і схоже, що анотація @ScopedProxyбула замінена на @RequestScopeта інші. Приклади ви можете знайти тут: logicbig.com/tutorials/spring-framework/spring-core/…
adebasi

1
Ми можемо сказати, що коли @Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)використовується нотація , SpringMVC не використовує WebApplicationContext для Autowired, натомість використовує CGLIB для створення проксі ?. Тут інше пояснення з прикладами , виконаними
Kurapika

0

Випробувавши різні параметри, вказані тут, та весняну документацію, я чомусь зрозумів, що Spring MVC - це контролер автоматичного підключення, коли ви використовуєте анотацію @Controller, і де у вашому веб-сайті є більше одного такого контролера. Змінено примітку до @RestController (значення = "UniqueControllerv1"), проблема вирішена.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.