fasola proxy o zasięgu sprężynowym

98

Czy ktoś może wyjaśnić użycie @ScopedProxyadnotacji wiosennej ? Myślałem , że ma to coś wspólnego z fasolą sesyjną, ale nie jestem pewien co.

Używając zakresów, użyłem fasoli z zakresem sesji bez @ScopedProxyadnotacji (lub bez serwerów proxy z zakresem aop), więc jestem naprawdę pewien, jak prawidłowo go używać.

Jeff Storey
źródło
sprawdź dokumentację fasoli . Sesja to jeden z zakresów , ale nie jedyny.
Gus,
1
@Gus, zdaję sobie sprawę z zakresów, ale nie jestem pewien, jak w to działa proxy z określonym zakresem
Jeff Storey,
1
Sekcja 3.4.4.5 jest moim zdaniem całkiem dobrym wyjaśnieniem tego, co robi proxy z określonym zakresem. - fragment pomiędzy dwoma przykładami jest ważną częścią.
Gus,
2
Tak, to wyjaśnia, dzięki. Jeśli chcesz dodać odpowiedź na pytanie, przyjmuję.
Jeff Storey,

Odpowiedzi:

249

Sekcja 3.4.4.5 dokumentacji wiosennej wyjaśnia to całkiem dobrze:

(należy pamiętać, że następująca definicja fasoli „userPreferences” w obecnej postaci jest niekompletna):

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

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

Z powyższej konfiguracji jasno wynika, że ​​do pojedynczego komponentu bean „userManager” wstrzykuje się odwołanie do komponentu bean HTTP o zasięgu sesji „userPreferences”. Najistotniejsze jest tutaj to, że komponent bean „userManager” jest singletonem … zostanie utworzony dokładnie raz na kontener , a jego zależności (w tym przypadku tylko jedna, fasola „userPreferences”) również zostaną wstrzyknięte (raz! ) .

Oznacza to, że „userManager” będzie (koncepcyjnie) działał tylko na dokładnie tym samym obiekcie „userPreferences”, czyli tym, z którym został pierwotnie wstrzyknięty.

To nie jest to, czego chcesz, gdy wstrzykujesz komponent bean o zasięgu sesji HTTP jako zależność do współpracującego obiektu (zazwyczaj). Raczej to , czego chcemy, to pojedynczy obiekt „userManager” na kontener , a następnie, przez cały okres istnienia sesji HTTP, chcemy widzieć i używać obiektu „userPreferences”, który jest specyficzny dla wspomnianej sesji HTTP .

Raczej to, czego potrzebujesz, to wstrzyknięcie jakiegoś obiektu, który ujawnia dokładnie ten sam interfejs publiczny co klasa UserPreferences (najlepiej obiekt będący instancją UserPreferences) i który jest wystarczająco inteligentny, aby móc uruchomić i pobrać prawdziwy obiekt UserPreferences z dowolnego wybranego przez nas mechanizmu określania zakresu (żądanie HTTP, sesja itp.). Następnie możemy bezpiecznie wstrzyknąć ten obiekt proxy do komponentu bean „userManager”, który będzie błogo nieświadomy, że odwołanie UserPreferences, do którego się trzyma, jest proxy .

W naszym przypadku, gdy instancja UserManager wywołuje metodę na obiekcie UserPreferences z iniekcją zależności, tak naprawdę będzie wywoływać metodę na serwerze proxy ... serwer proxy wyłączy się i pobierze rzeczywisty obiekt UserPreferences z (w tym przypadku) sesji HTTP i deleguj wywołanie metody do pobranego rzeczywistego obiektu UserPreferences.

Dlatego podczas wstrzykiwania komponentów bean o zasięgu żądania, sesji i globalSession do współpracujących obiektów potrzebujesz następującej, poprawnej i kompletnej konfiguracji:

<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
źródło
Więc kiedy używam adnotacji @ScopedProxy, serwer proxy zostanie automatycznie użyty i to wszystko? ScopedProxy oznacza -> Nie używaj tej klasy w obecnej postaci, użyj do niej proxy?
Koray Tugay
3
Używam spring-web: 4.3.3 i wygląda na to, że adnotacja @ScopedProxyzostała zastąpiona przez @RequestScopei innymi. Przykłady można znaleźć tutaj: logicbig.com/tutorials/spring-framework/spring-core/ ...
adebasi
1
Moglibyśmy powiedzieć, że kiedy @Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)używana jest notacja , SpringMVC nie używa WebApplicationContext dla Autowired, zamiast tego używa CGLIB do tworzenia proxy ?. Oto inne wyjaśnienie z przykładami out
Kurapika
0

Po wypróbowaniu różnych opcji określonych tutaj i dokumentacji sprężynowej, z jakiegoś powodu doszedłem do wniosku, że Spring MVC jest dziwnie autowiring kontrolerem, gdy używasz adnotacji @Controller i masz więcej niż jeden taki kontroler w swojej aplikacji internetowej. Zmodyfikowano adnotację na @RestController (value = "UniqueControllerv1"), problem został rozwiązany.

geeksquad87
źródło