2009-06-20 3 views
7

Nach dem Start meiner Webapp in Tomcat 6.0.18, Bootstrap Spring mit nur was ist notwendig, initialisieren das System - und zwar für jetzt, Datenbank Migrationen. Ich möchte nicht, dass ein Teil des Systems geladen wird, bis die Migrationen erfolgreich abgeschlossen wurden. Dies verhindert, dass die anderen Beans warten müssen, bis die Migrationen abgeschlossen sind, bevor sie ausgeführt oder sogar instanziiert werden.Kann ich zusätzliche Spring-Konfigurationsdateien dynamisch in einen vorhandenen WebApplicationContext laden?

Ich habe eine startup-appcontext.xml konfiguriert mit einer dbMigrationDAO, eine startupManager, die eine ThreadPoolExecutor ist, und schließlich eine FullSystemLauch-Bean. Ich übergebe eine Liste von Konfigurationsorten an die FullSystemLaunch-Bohne über Setter-Injektion. Die FullSystemLaunch-Bean implementiert ServletContextAware, erhält einen Verweis auf die aktuelle WebApplicationContext und somit kann ich eine ConfigurableListableBeanFactory haben. Leider gibt diese Bean-Factory isConfigurationFrozen() true zurück, so dass der Aufruf von beanFactory.setConfigLocations (configLocations) keine Auswirkungen hat.

Kann ich dies erreichen oder verhindert Spring dies, weil es etwas ungewöhnlich ist? Es scheint vernünftig, wenn verstanden, aber auch ein bisschen gefährlich. Und ja, ich bin bereit den aktuellen Kontext wegzublasen b/c die aktuell geladenen Singletons werden nach Abschluss der Initialisierung nicht benötigt.

Vielen Dank für die Hilfe.

Antwort

2

Sie könnten den vorhandenen Kontext als übergeordneten Kontext für die anderen Kontexte verwenden, obwohl ich bezweifle, dass Sie den vorhandenen WebApplicationContext ersetzen können.

Wenn Sie das EAR-WAR-Paket verwenden, erhalten Sie dieses Out-of-the-Box (so), indem Sie einen Anwendungskontext aus dem EAR laden und dann einen im WAR hinzufügen.

Nicht sicher, ob dies in Ihrer Situation anwendbar ist.

0

Könnte lazy-initialization eine Alternative für das sein, was Sie erreichen möchten?

+0

Nein; Es müsste immer noch Logik in jeder der Beans geben, um zu verhindern, dass sie entweder instanziiert wird oder "ihre Arbeit macht", bevor das System initialisiert wird. – Elliot

+1

Warum nicht einfach alle Bohnen zu faul setzen. Erstellen Sie dann eine Halte-Bean, die ebenfalls lazy-initialisiert ist, und fügen Sie alle anderen Beans als Abhängigkeiten hinzu. Wenn Sie beanContext.getBean ("mybean") aufrufen, werden alle Beans instanziiert. – kgiannakakis

3

Meine Meinung wäre, Spring zu erlauben, Ihre Bohnen zu initialisieren, wenn es passt - in der Reihenfolge ihrer erklärten Abhängigkeiten.

Wenn Sie Datenbankmigrationen benötigen gibt es ein paar Muster zuerst sie laufen zu lassen:

  • wenn Sie mit Hibernate/JPA Ihre session machen/PersistenceManager abhängen-on die Migration Bohnen;
  • wenn Sie Ebene JDBC erstellen einen Wrapper Datasource und in seiner init-Methode verwenden die Migrationen (code sample)

Der Vorteil berufen ist klar: Einfachheit.

0

Sie können den WebApplicatonContext auf ConfigurableWebApplicationContext upkat dann verwenden Sie die setConfigurations-Methode.

nicht vergessen erfrischen;

0

Es gab die gleiche Aufgabe und ich erstellte zwei Kontexte: startUpContext.xml und applicationContext.xml.In startUpContext.xml gibt es eine Bean, die das Laden von appliationContext.xml auslöst. (Der Speicherort des Anwendungskontexts ist in startUpContext.xml als Eigenschaft eines Triggers konfiguriert.) Und schließlich der Auslöser ersetzt Stellen des aktuellen Kontexts und erfrischt:

applicationContext.setConfigLocations(locations); 
applicationContext.refresh(); 

(startUpContext.xml ist mit einem Standard-Feder Kontext loader Hörer geladen)