Gibt es eine Spring 3-Funktion, mit der einige Methoden ausgeführt werden können, wenn die Anwendung zum ersten Mal gestartet wird? Ich weiß, dass ich den Trick machen kann, eine Methode mit @Scheduled
Annotation festzulegen, und sie wird direkt nach dem Start ausgeführt, aber dann wird sie regelmäßig ausgeführt.
176
Antworten:
Wenn Sie mit "Anwendungsstart" "Anwendungskontextstart" meinen, dann gibt es viele Möglichkeiten, dies zu tun . Die einfachste (für Singletons Beans jedenfalls) besteht darin, Ihre Methode mit Anmerkungen zu versehen
@PostConstruct
. Schauen Sie sich den Link an, um die anderen Optionen zu sehen, aber zusammenfassend sind dies:@PostConstruct
afterPropertiesSet()
wie durch die definiertInitializingBean
Rückrufschnittstelle definiertTechnisch gesehen sind dies Haken in die Bohne Lebenszyklus als in den Kontext-Lebenszyklus, aber in 99% der Fälle sind beide gleichwertig.
Wenn Sie sich speziell mit dem Starten / Herunterfahren des Kontexts befassen müssen, können Sie stattdessen die
Lifecycle
Schnittstelle implementieren , dies ist jedoch wahrscheinlich nicht erforderlich .quelle
Access restriction: The type PostConstruct is not accessible due to restriction on required library /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/rt.jar
@PostConstruct
Methode aufgerufen, aber die JMS-Infrastruktur, von der sie indirekt abhing, war noch nicht vollständig verkabelt (und als Spring schlug alles nur stillschweigend fehl). Beim Umschalten auf@EventListener(ApplicationReadyEvent.class)
alles , was funktioniert hat (ApplicationReadyEvent
ist Spring Boot spezifisch für Vanilla Spring, siehe Stefans Antwort).Dies ist einfach mit einem
ApplicationListener
. Ich habe das zum Arbeiten gebracht, um Spring's zu hörenContextRefreshedEvent
:Anwendungslistener werden im Frühjahr synchron ausgeführt. Wenn Sie sicherstellen möchten, dass Ihr Code nur einmal ausgeführt wird, behalten Sie einfach einen bestimmten Status in Ihrer Komponente bei.
AKTUALISIEREN
Ab Spring 4.2+ können Sie auch die
@EventListener
Anmerkung verwenden, um Folgendes zu beobachtenContextRefreshedEvent
(danke an @bphilipnyc für den Hinweis):quelle
ContextStartedEvent
stattdessen zu verwenden , ist es schwieriger, den Listener hinzuzufügen, bevor das Ereignis ausgelöst wird.In Spring 4.2+ können Sie jetzt einfach Folgendes tun:
quelle
Wenn Sie Spring-Boot verwenden, ist dies die beste Antwort.
Ich denke, dass
@PostConstruct
und andere verschiedene Lebenszyklusinterjektionen ein Umweg sind. Diese können direkt zu Laufzeitproblemen führen oder aufgrund unerwarteter Bean / Kontext-Lebenszyklusereignisse weniger als offensichtliche Fehler verursachen. Warum rufen Sie Ihre Bean nicht einfach direkt mit Java auf? Sie rufen die Bohne immer noch auf "Spring Way" auf (z. B. über den Spring AoP-Proxy). Und das Beste ist, es ist einfach Java, einfacher geht es nicht. Keine Notwendigkeit für Kontext-Listener oder ungerade Scheduler.quelle
main()
, beispielsweise bei Verwendung eines Anwendungsframeworks (z. B. JavaServer Faces).Für Java 1.8-Benutzer, die eine Warnung erhalten, wenn sie versuchen, auf die @ PostConstruct-Annotation zu verweisen, habe ich stattdessen die @ Scheduled-Annotation huckepack genommen, die Sie ausführen können, wenn Sie bereits einen @ Scheduled-Job mit fixedRate oder fixedDelay haben.
quelle
Was wir getan haben, war zu erweitern
org.springframework.web.context.ContextLoaderListener
, um etwas zu drucken, wenn der Kontext beginnt.Konfigurieren Sie die Unterklasse dann in
web.xml
:quelle
Mit SpringBoot können wir beim Start eine Methode über ausführen
@EventListener
Annotationquelle
Sie können auch eine geplante Methode verwenden, bei der fixedDelay sehr hoch eingestellt ist
Dies hat den Vorteil, dass die gesamte Anwendung verkabelt ist (Transaktionen, Dao, ...)
Dies wird unter Planen der einmaligen Ausführung von Aufgaben mithilfe des Spring-Task-Namespace angezeigt
quelle
@PostConstruct
?Es wurde eine andere Lösung veröffentlicht, die WebApplicationInitializer implementiert und viel aufgerufen wird, bevor eine Spring Bean instanziiert wird, falls jemand diesen Anwendungsfall hat
Initialisieren Sie das Standardgebietsschema und die Standardzeitzone mit der Spring-Konfiguration
quelle
quelle
Wenn Sie eine Bean konfigurieren möchten, bevor Ihre Anwendung vollständig ausgeführt wird, können Sie Folgendes verwenden
@Autowired
:quelle
Sie können
@EventListener
für Ihre Komponente verwenden, die aufgerufen wird, nachdem der Server gestartet und alle Beans initialisiert wurden.quelle
Für eine Datei
StartupHousekeeper.java
im Paketcom.app.startup
:Tun Sie dies in
StartupHousekeeper.java
:Und das in
myDispatcher-servlet.java
:quelle