web-dev-qa-db-fra.com

haricot proxy de printemps

Quelqu'un peut-il expliquer l'utilisation de l'annotation print@ScopedProxy? Je pensais cela avait quelque chose à voir avec les haricots à la session, mais je ne sais pas trop quoi.

Dans mon utilisation des scopes, j'ai utilisé des beans scoped de session sans l'annotation @ScopedProxy (ou sans proxys aop scoped), donc je suis vraiment sûr de savoir comment l'utiliser correctement.

89
Jeff Storey

La section 3.4.4.5 de la documentation de printemps l'explique assez bien:

(Veuillez noter que la définition de bean 'userPreferences' suivante est incomplète):

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

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

Dans la configuration ci-dessus, il est évident que le bean singleton 'userManager' est injecté avec une référence au bean HTTP de la session, 'userPreferences'. Le point saillant ici est que le bean le bean 'userManager' est un singleton ... ce sera instancié exactement une fois par conteneur, et ses dépendances (dans ce cas, un seul, le bean 'userPreferences') sera également uniquement injecté (une fois!).

Cela signifie que "userManager" ne fonctionnera (conceptuellement) que sur le même objet "userPreferences", c'est-à-dire celui avec lequel il a été injecté à l'origine.

Ce n'est pas ce que vous voulez lorsque vous injectez un bean HTTP Session-scoped en tant que dépendance dans un objet collaborant (généralement). Au lieu de cela, ce que nous voulons, c'est un seul objet 'userManager' par conteneur, puis pendant la durée de vie d'une session HTTP, nous souhaitons voir et utiliser un ' objet userPreferences spécifique à ladite session HTTP.

Vous devez plutôt injecter une sorte d'objet qui expose exactement la même interface publique que la classe UserPreferences (idéalement un objet qui est une instance de UserPreferences) et qui est suffisamment intelligent pour pouvoir aller chercher le véritable objet UserPreferences. quel que soit le mécanisme de portée sous-jacent choisi (requête HTTP, session, etc.). Nous pouvons ensuite injecter cet objet proxy en toute sécurité dans le bean 'userManager', qui ne sera certainement pas conscient du fait que la référence UserPreferences qu'il détient est un proxy

Dans notre cas, lorsqu'une occurrence de UserManager appelle une méthode sur l'objet UserPreferences à dépendance injectée, elle invoquera réellement une méthode sur le proxy} _ ... le proxy s'éteindra et récupérera l'objet UserPreferences réel provient (dans ce cas) de la session HTTP et délègue l'invocation de la méthode à l'objet UserPreferences réel récupéré.

C'est pourquoi vous avez besoin de la configuration suivante, correcte et complète, lorsque vous injectez des beans demandés, session et globalSession dans des objets en collaboration:

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

Après avoir essayé différentes options spécifiées ici et la documentation de spring, j'ai découvert pour une raison quelconque Spring MVC, un contrôleur automatique de câblage automatique lorsque vous utilisez l'annotation @Controller et où vous avez plusieurs contrôleurs de ce type dans votre application Web. Modification de l'annotation en @RestController (value = "UniqueControllerv1"), le problème est résolu.

0
gr12828710