Federbohnende Proxy-Bohne

98

Kann jemand die Verwendung der Frühlingsanmerkung erklären @ScopedProxy? Ich dachte, es hätte etwas mit Sitzungsbohnen zu tun, aber ich bin mir nicht ganz sicher, was.

Bei der Verwendung von Bereichen habe ich Beans mit Sitzungsbereich ohne die @ScopedProxyAnnotation (oder ohne Prox mit AOP-Bereich) verwendet, daher bin ich mir wirklich sicher, wie ich sie richtig verwenden soll.

Jeff Storey
quelle
Lesen Sie die Bean-Dokumentation . Sitzung ist einer der Bereiche , aber nicht der einzige.
Gus
1
@ Gus, ich bin mir der Bereiche bewusst, nur nicht sicher, wie Scoped Proxy in das spielt
Jeff Storey
1
Abschnitt 3.4.4.5 ist meiner Meinung nach eine ziemlich gute Erklärung dafür, was ein Proxy mit Gültigkeitsbereich tut. - Das Bit zwischen den beiden Beispielen ist der wichtige Teil.
Gus
2
Ja, das erklärt es, danke. Wenn Sie eine Antwort auf die Frage hinzufügen möchten, werde ich akzeptieren.
Jeff Storey

Antworten:

248

Abschnitt 3.4.4.5 der Frühlingsdokumente erklärt es ziemlich gut:

(Bitte beachten Sie, dass die folgende Bean-Definition 'userPreferences' derzeit unvollständig ist):

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

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

Aus der obigen Konfiguration geht hervor, dass der Singleton-Bean 'userManager' mit einem Verweis auf die HTTP-Bean 'userPreferences' mit Sitzungsbereich eingefügt wird. Der herausragende Punkt hierbei ist, dass die 'userManager'-Bean ein Singleton ist ... sie wird genau einmal pro Container instanziiert , und ihre Abhängigkeiten (in diesem Fall nur eine, die' userPreferences'-Bean) werden ebenfalls nur einmal injiziert! ) .

Dies bedeutet, dass der 'userManager' (konzeptionell) immer nur mit genau demselben 'userPreferences'-Objekt arbeitet, mit dem er ursprünglich injiziert wurde.

Dies ist nicht das, was Sie möchten, wenn Sie eine HTTP-Bean mit Sitzungsbereich als Abhängigkeit (normalerweise) in ein zusammenarbeitendes Objekt einfügen. Wir möchten vielmehr ein einzelnes 'userManager'-Objekt pro Container . Anschließend möchten wir für die Lebensdauer einer HTTP-Sitzung ein' userPreferences'-Objekt anzeigen und verwenden , das für diese HTTP-Sitzung spezifisch ist .

Sie müssen dann eher eine Art Objekt einfügen, das genau dieselbe öffentliche Schnittstelle wie die UserPreferences-Klasse verfügbar macht (idealerweise ein Objekt, das eine UserPreferences-Instanz ist) und das intelligent genug ist, um das echte UserPreferences-Objekt abrufen zu können von dem zugrunde liegenden Scoping-Mechanismus, den wir ausgewählt haben (HTTP-Anforderung, Sitzung usw.). Wir können dieses Proxy-Objekt dann sicher in die 'userManager'-Bean einfügen, die glücklicherweise nicht weiß, dass die UserPreferences-Referenz, an der sie festhält, ein Proxy ist .

In unserem Fall ruft eine UserManager-Instanz , wenn sie eine Methode für das in Abhängigkeit injizierte UserPreferences-Objekt aufruft, tatsächlich eine Methode für den Proxy auf . Der Proxy geht dann aus und ruft das echte UserPreferences-Objekt ab (in diesem Fall). die HTTP-Sitzung und delegieren Sie den Methodenaufruf an das abgerufene echte UserPreferences-Objekt.

Aus diesem Grund benötigen Sie die folgende korrekte und vollständige Konfiguration, wenn Sie Beans mit Anforderungs-, Sitzungs- und globalem Sitzungsbereich in zusammenarbeitende Objekte einfügen:

<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
quelle
Wenn ich also die Annotation @ScopedProxy verwende, wird automatisch ein Proxy verwendet, und das ist alles? ScopedProxy bedeutet -> Verwenden Sie diese Klasse nicht so wie sie ist, verwenden Sie einen Proxy dafür?
Koray Tugay
3
Ich verwende Spring-Web: 4.3.3 und es sieht so aus, als ob die Anmerkung @ScopedProxydurch @RequestScopeund andere ersetzt wurde. Beispiele finden Sie hier: Logicbig.com/tutorials/spring-framework/spring-core/…
Adebasi
1
Wir könnten sagen, wenn die Notation @Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)verwendet wird, verwendet SpringMVC nicht WebApplicationContext für Autowired, sondern CGLIB zum Erstellen des Proxys. Hier andere Erklärung mit Beispielen aus
Kurapika
0

Nachdem ich verschiedene hier angegebene Optionen und die Spring-Dokumentation ausprobiert habe, habe ich aus irgendeinem Grund herausgefunden, dass Spring MVC ein seltsam automatisch verdrahtender Controller ist, wenn Sie die @ Controller-Annotation verwenden und wenn Sie mehr als einen solchen Controller in Ihrer Webanwendung haben. Die Annotation wurde in @RestController geändert (Wert = "UniqueControllerv1"). Das Problem wurde behoben.

geeksquad87
quelle