JSF - Session-scoped managed bean nicht über Abhängigkeiten re-injiziert Sitzung der Deserialisierung
Ich bin mir nicht sicher, ob das was ich mache falsch ist, oder ob ich einfach nur verpasst, eine Anmerkung oder configuration item irgendwo. Hier ist die situation:
Ich habe eine JSF-Anwendung mit einer session-scoped bean mit dem Namen SessionData
. Diese Bohne hat ein application-scoped bean-Referenz (Typ ApplicationData
) injiziert Zeitpunkt der Erstellung. Dies funktioniert ok, wenn die Sitzung zum ersten mal erstellt. Die dependency injection ist fertig mit <managed-bean>
Elemente in der faces-config.xml
Datei wie hier gezeigt:
<managed-bean>
<managed-bean-name>sessionData</managed-bean-name>
<managed-bean-class>my.package.SessionData</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>applicationData</property-name>
<property-class>my.package.ApplicationData</property-class>
<value>#{applicationData}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>applicationData</managed-bean-name>
<managed-bean-class>my.package.ApplicationData</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
Weil es nicht sinnvoll ist, haben meine SessionData
Objekt sind die ApplicationData
Objekt, wenn es serialisiert, ich habe markiert die ApplicationData
Referenz als transient in meinem SessionData
Objekt:
transient private ApplicationData applicationData;
Alles ist gut, bis der web-Anwendung wird beendet (in meinem Tomcat 6.x-container) und die Sitzungen serialisiert werden. Wenn ich die Anwendung neu starten und die Sitzungen sind deserialisiert, mein Verweis auf ApplicationData
ist nicht re-injiziert durch JSF. Ich weiß, dass der Deserialisierung ist eigentlich verlassen transient-Felder ohne Wert. Gibt es eine Möglichkeit zu signalisieren, JSF, dass diese session-scoped Objekt erfordert seine Abhängigkeiten festgelegt werden, wieder nach der Deserialisierung?
Bin ich mit MyFaces JSF 1.2 und Tomcat 6.0.26 als meine web application container.
- Es wurde vorgeschlagen, dass ich liefern eine readObject () - Methode, und legen Sie manuell das ApplicationData-Objekt dort während der Deserialisierung mithilfe der FacesContext. Ich glaube nicht, dass das funktionieren wird, da der FacesContext ist nur während der Lebensdauer einer Anfrage. Die Deserialisierung geschieht beim Start der Anwendung.
- richtig, das ist, warum ich gelöscht meine Antwort. Es erscheint eher kompliziert (daher +1 für die Frage)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Obwohl die angebotene Lösung von Bozho funktionieren könnte, möchte ich nicht vorstellen-proxy-Objekte in einer Anwendung, die derzeit nicht mit Ihnen. Meine Lösung ist weniger als ideal, aber es bekommt den job getan.
Verließ ich das transiente Feld in Ort:
Ich auch Links die setter statt, so dass JSF-zunächst legen Sie die Referenz, wenn die
SessionData
- Objekt erstellt, das erste mal:Die Veränderung, die ich machte, war in der getter-Methode. Methoden in der
SessionData
Objekt jetzt aufhören müssen, direkt auf die_applicationData
Feld und stattdessen die Referenz über den getter. Der getter wird zuerst überprüfen, ob ein null-Verweis. Wenn es null ist, dann ist die managed bean ist die über dieFacesContext
. Die Einschränkung hier ist, dass dieFacesContext
ist nur während der Lebensdauer einer Anfrage.Wenn jemand interessiert, hier ist der code für meine
getManagedBean()
Methode:Und pflücke nicht auf meine Anrufe Überprüfen. Ich nehme Sie aus, nachdem ich fertig bin mit der Entwicklung! 🙂
Application#evaluateExpressionGet()
. Siehe auch die Antwort.können Sie eine Methode hinzufügen:
Und in
initializeApplicationData
Sie können ein dynamisches proxy-Objekt. Mithilfe von CGLIB oder javassist erstellen Sie eine proxy, die vor jedem Methodenaufruf setzt eine interne Feld - die echteApplicationData
. Wenn esnull
, dann Holen Sie sich die aktuellenFacesContext
werden (einsehbar) und die verwaltete bean von dort aus durch:delegieren, um seine Methoden.
Dies ist ein hässlicher workaround, aber ich denke, es wird funktionieren.