ich habe ein Problem mit Spring Scopes, bei dem ich einfach nicht
weiter komme. Ich habe in letzter Zeit viel mit Spring gearbeitet, das
ist aber trotzdem mein erstes Projekt damit.
Die betreffende Anwendung besteht aus diversen Beans, die über Setter
Injection miteinander verknüpft sind. So gut wie alle Beans sind
Singletons (Default Scope). Die Schnittstelle der Anwendung nach
aussen ist eine Bean, die als Web Service Endpunkt bereit gestellt
wird. Auf der anderen Seite wurde die Anwendung jetzt so erweitert,
dass sie auch regelmässig per TimerTask gestartet. Das Problem ist
jetzt, dass die Bean MetaDataContainer als scope="request"
konfiguriert ist. Das geht dann auch gut, wenn eine Anfrage an den Web
Service kommt. Es existiert damit ein HTTP Request, also auch eine
dazugehörige Instanz von MetaDataContainer. Wird die Anwendung aber
über den TimerTask getriggert, dann gibt es natürlich keinen HTTP
Request. In diesem Fall wird überall, wo MetaDataContainer injected
wird, null injected -> Anwendung schmiert ab.
Ich habe mal versucht, den Aufbau der Anwendung und des Problems
vereinfacht darzustellen:
<jaxws:endpoint id="propagationReceiverWebService"
implementorClass="PropagationReceiverServiceImpl"
implementor="#propagationReceiverService" address="/
propagationReceiverService">
</jaxws:endpoint>
<bean id="propagationReceiverService"
class="PropagationReceiverServiceImpl">
<property name="nativeDataService" ref="nativeDataService" />
</bean>
<bean id="nativeDataService" class="NativeDataServiceImpl">
<property name="metaDataContainer" ref="metaDataContainer" />
</bean>
<bean id="metaDataContainer" class="MetaDataContainerImpl"
scope="request">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
<bean id="pollingTask"
class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="1000" />
<property name="period" value="10000" />
<property name="timerTask" ref="pollingNotificationExecutor" />
</bean>
<bean id="pollingNotificationExecutor"
class="pollingNativeDataObservationService">
<property name="metaDataContainer" ref="metaDataContainer" />
</bean>
Eine Lösung des Problems wäre ein Scope, der sich entweder wie ein
Request Scope oder aber wie ein Thread Scope verhält. Wenn es einen
aktuellen HTTP Request gibt, dann soll wie bisher auch ein Request
Scope genutzt werden, ansonsten ein Thread Scope. Geht sowas? Wie gehe
ich da ran? Oder kann man das Problem evtl. ganz anders lösen?
Mir fehlt momentan völlig der Überblick, wo ich da bei Spring ansetzen
muss, um sowas hinzukriegen. Ich bin dankbar für jede Hilfe.
Viele Grüße
Florian
--
Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe Spring User Group Germany beigetreten sind.
Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine E-Mail an su...@googlegroups.com.
Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an sugg+uns...@googlegroups.com.
Besuchen Sie die Gruppe unter http://groups.google.com/group/sugg?hl=de, um weitere Optionen zu erhalten.
ich würde für einen eigenen Scope schreiben, der von RequestScope erbt.
Dort kann man dann noch das ganze in einen ThreadLocal speichern, wenn
man es nicht in den Reuqest bekommt.
Den Scope kannst Du registrieren - siehe Abschnitt 3.4.5.2 in der
Spring-2.5-Referenz-Dokumentation oder Abschnitt 3.5.5.2 in der
Spring-3.0-Dokumentation.
HTH,
Eberhard
Am 27.01.10 09:29, schrieb Florian:
> --
> Sie haben diese Nachricht erhalten, da Sie der Google Groups-Gruppe
> Spring User Group Germany beigetreten sind.
> Wenn Sie Nachrichten in dieser Gruppe posten möchten, senden Sie eine
> E-Mail an su...@googlegroups.com.
> Wenn Sie aus dieser Gruppe austreten möchten, senden Sie eine E-Mail an
> sugg+uns...@googlegroups.com.
> Besuchen Sie die Gruppe unter http://groups.google.com/group/sugg?hl=de,
> um weitere Optionen zu erhalten.
>
--
Eberhard Wolff
Regional Director
SpringSource - A division of VMware
Sitz der Gesellschaft:
VMware Global, Inc. - Freisinger Strasse 3 - 85716
Unterschleissheim-Lohhof Geschäftsführer: Joanne Holloway, Tom Jurewicz
Amtsgericht München HRB 149743
Author, "Spring 2 - Framework für die Java Entwicklung"
http://www.spring-buch.de/
Founding Member Java Champions
https://java-champions.dev.java.net/
Mail: eberhar...@springsource.com
Skype: ebr.wolff
Blog: http://JandIandMe.blogspot.com/
Mailing List: http://www.springsource.com/newsletter
erstmal vielen Dank für die schnelle und kompetente Hilfe.
Mein Ansatz war, ähnlich wie von euch vorgeschlagen, ein neuer Scope.
Dieser neue Scope soll sich wenn möglich wie ein RequestScope
verhalten, ansonsten wie ein ThreadScope. Ich habe das ganze dann auch
implementiert. Mein neuer Scope leitet alle Anfragen an einen der
beiden genannten Scopes weiter (Decorator Pattern). Hier der Ansatz
mal exemplarisch an einer der Scope Methoden:
public class RequestOrThreadScope implements Scope {
@Override
public Object get(String name, ObjectFactory objectFactory) {
Object result = null;
try {
result = requestScope.get(name, objectFactory);
} catch (Exception e) {
// TODO
}
if (result == null) {
result = threadScope.get(name, objectFactory);
}
return result;
}
}
Leider hat das ganze so nicht funktioniert. Die Ursache dafür ist,
dass der TimerTask immer im gleichen Thread startet. Wenn der
TimerTask also das zweite mal läuft, dann gibt es im aktuellen Thread
bereits einen MetaDataContainer. Das packt dann die Anwendung nicht
und schmiert ab.
Ich habe das Problem jetzt so gelöst, dass beim Start des TimerTask
der aktuelle Thread erstmal "aufgeräumt" wird. Ist ein
MetaDataContainer vorhanden, wird der gelöscht:
ThreadScope t = new ThreadScope();
Object removed = t.remove("scopedTarget.metaDataContainer");
Damit funktioniert die Anwendung jetzt problemlos.
Danke für die Hilfe!
Florian
> > Besuchen Sie die Gruppe unterhttp://groups.google.com/group/sugg?hl=de,
> > um weitere Optionen zu erhalten.
>
> --
> Eberhard Wolff
> Regional Director
> SpringSource - A division of VMware
> Sitz der Gesellschaft:
> VMware Global, Inc. - Freisinger Strasse 3 - 85716
> Unterschleissheim-Lohhof Geschäftsführer: Joanne Holloway, Tom Jurewicz
> Amtsgericht München HRB 149743
>
> http://www.springsource.com
>
> Author, "Spring 2 - Framework für die Java Entwicklung"http://www.spring-buch.de/
>
> Founding Member Java Championshttps://java-champions.dev.java.net/
>
> Mail: eberhard.wo...@springsource.com