Wie kann die Entwicklung von Spring Boot mit DevTools beschleunigt und dieser Prozess unterhaltsamer und produktiver gestaltet werden?
Anpassung
Wie bei der Entwicklung von Spring Boot üblich, ist das Setup recht einfach. Alles, was Sie tun müssen, ist, die richtige Abhängigkeit hinzuzufügen, und schon sind Sie fertig. Spring Boot findet es und konfiguriert DevTools automatisch entsprechend.
Wenn Sie Maven verwenden:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
Bei Verwendung von Gradle:
configurations { developmentOnly runtimeClasspath { extendsFrom developmentOnly } } dependencies { developmentOnly("org.springframework.boot:spring-boot-devtools") }
Bitte beachten Sie, dass die Abhängigkeit als optional deklariert ist. Dies ist wichtig, da eine solche Abhängigkeitsdeklaration verhindert, dass die DevTools-Abhängigkeit je nach Projekt transitiv auf andere Module angewendet wird.
Automatischer Neustart
Immer wenn in Ihrem Klassenpfad Dateiänderungen auftreten, startet DevTools Ihre Arbeitsanwendung automatisch mit den neuen Änderungen neu. Für die lokale Entwicklung kann dies hilfreich sein, da Sie die Anwendung nicht manuell erneut bereitstellen müssen.
Dies allein wäre nicht so nützlich, da ein Neustart immer noch zu viel Zeit in Anspruch nehmen kann. Glücklicherweise ist ein solcher Neustart aufgrund des von DevTools verwendeten trickreichen Tricks viel schneller als ein regulärer Neustart.
Tatsache ist, dass Sie beim Entwickeln einer Anwendung normalerweise eine oder mehrere Klassen ändern und die Ergebnisse in Ihrer laufenden Anwendung auf Feedback überprüfen möchten. Sie nehmen geringfügige Änderungen an Ihrer Anwendung vor, während die meisten geladenen Klassen aus Frameworks und Bibliotheken von Drittanbietern stammen.
Unter der Haube von Spring DevTools werden zwei Klassenlader verwendet -
base und
restart . Klassen, die sich nicht ändern, werden von der Base Loader
Base geladen. Die Klassen, mit denen Sie arbeiten, werden mit dem
Restart Loader geladen. Bei jedem Neustart wird der Bootloader neu erstellt. Daher ist der Neustart der Anwendung viel schneller als üblich und kann eine echte Alternative zum erneuten Laden einer dynamischen Klasse mit Tools wie JRebel sein.
Initialisierung des Neustarts in der IDE
Ein Neustart wird jedes Mal ausgelöst, wenn sich eine Datei in Ihrem Klassenpfad ändert. Dieser Vorgang hängt jedoch von Ihrer IDE ab. Das bedeutet, dass es nicht ausreicht, nur Ihre Java-Dateien zu ändern. Das Wichtigste ist, wenn Ihre IDE tatsächlich .class-Dateien in Ihrem Klassenpfad aktualisiert.
Wenn Sie IntelliJ IDEA verwenden, müssen Sie den Befehl build in Ihrem Projekt ausführen (
Strg + F9 oder
Build → Build Project ). Sie können
den Build-Befehl auch so
konfigurieren, dass er in IDEA automatisch ausgeführt wird . Darüber hinaus können Sie die Spring Boot-Startkonfiguration öffnen und bestimmen, was beim Start der Anwendungsaktualisierung geschieht (
Strg + F10 ):

Im ersten Kombinationsfeld können Sie die
Auslöserdatei aktualisieren auswählen, um den Neustart von DevTools jedes Mal zu starten, wenn die
Aktualisierungsaktion ausgeführt wird. Alternativ können Sie auch die
Hot-Swap- Option auswählen und versuchen, die Anwendung nur dann mit DevTools neu zu starten, wenn die
Hot-Swap- Ausführung fehlgeschlagen ist.
Im zweiten Kombinationsfeld können Sie den Neustart aller statischen Ressourcen und Vorlagen konfigurieren, wenn das IDEA-Fenster den Fokus verliert (z. B. beim Wechsel zum Browserfenster).
In Eclipse ist es einfach genug, Ihre Dateien zu speichern.
Nur für die Entwicklung
Spring Boot DevTools sind nur für die Entwicklung und nicht für den Produktionsbetrieb der Anwendung vorgesehen. Wenn Ihre Anwendung feststellt, dass Sie in einer Produktionsumgebung arbeiten, wird DevTools automatisch deaktiviert.
Zu diesem Zweck wird Ihre Anwendung immer dann als Produktionsanwendung betrachtet, wenn Sie sie als vollständig gepacktes Artefakt starten, z. B. als JAR mit integriertem Anwendungsserver:
java -jar devtools-example-1.0.0.jar
Gleiches gilt, wenn Ihre Anwendung über ein spezielles Klassenladeprogramm gestartet wird, z. B. auf einem Anwendungsserver.
Wenn Sie hingegen entpackte Artefakte ausführen (z. B. in Ihrer IDE), wird Ihre Anwendung im Entwicklungsmodus betrachtet. Gleiches gilt für die Verwendung des Spring-Boot-Plugins zum Ausführen der Anwendung:
Maven:
mvn spring-boot:run
Gradle:
gradle bootRun
LiveReload
LiveReload ist ein nützliches Tool, mit dem Sie eine Seite in einem Browser sofort
aktualisieren können, wenn Sie Änderungen an Dateien wie HTML, CSS, Bildern
usw. vornehmen. Dateien werden sogar nach Bedarf vorverarbeitet - dies bedeutet eine automatische Kompilierung von SASS- oder LESS-Dateien.

Spring DevTools startet automatisch eine lokale Instanz des LiveReload-Servers, die Ihre Dateien verfolgt. Alles was Sie tun müssen, ist die
Erweiterung für den Browser zu installieren und fertig. Es ist nicht nur nützlich, um die externe Schnittstelle Ihrer Anwendung zu entwickeln (falls Sie sie als Teil des Spring-Anwendungsartefakts verteilen), sondern kann auch zum Überwachen und erneuten Laden der Ausgabe Ihrer REST-API verwendet werden.
Eigenschaft überschreiben
Wenn Sie eine Anwendung lokal entwickeln, haben Sie normalerweise andere Konfigurationsanforderungen als in einer Produktionsumgebung. Ein Beispiel wäre das Cachen. In einer Produktionsumgebung ist die Abhängigkeit von verschiedenen Caches (wie Engine-Vorlagen-Caches, Caching-Headern für statische Ressourcen usw.) äußerst wichtig. Während der Entwicklung werden möglicherweise alte Daten verwendet, die Ihre neuesten Änderungen nicht widerspiegeln. Ein weiteres Beispiel wäre die erweiterte Protokollierung, die bei der Entwicklung hilfreich sein kann, für die Produktionsumgebung jedoch zu detailliert ist.
Es ist zu schwierig, zwei Konfigurationsarten selbst zu verwalten. Die gute Nachricht ist, dass Spring Boot DevTools standardmäßig viele Eigenschaften für Ihre lokale Entwicklung einrichtet.
spring.thymeleaf.cache=false spring.freemarker.cache=false spring.groovy.template.cache=false spring.mustache.cache=false server.servlet.session.persistent=true spring.h2.console.enabled=true spring.resources.cache.period=0 spring.resources.chain.cache=false spring.template.provider.cache=false spring.mvc.log-resolved-exception=true server.servlet.jsp.init-parameters.development=true spring.reactor.stacktrace-mode.enabled=true
Sie finden eine Liste aller Eigenschaften in der
DevToolsPropertyDefaultsPostProcessor- Klasse.
Remote-Verbindung
Zusätzlich zur lokalen Entwicklung können Sie auch eine Verbindung zu einer Remoteanwendung herstellen, in der DevTools ausgeführt wird. Dieses Tool ist nicht für Produktionsumgebungen vorgesehen, da es ein ernstes Sicherheitsrisiko darstellen kann. Es kann jedoch in einer Vorproduktionsumgebung sehr nützlich sein.
Aktivieren der Remoteverbindung
Die Remoteverbindung ist standardmäßig nicht aktiviert. Sie müssen es explizit aktivieren, indem Sie die pom-Datei ändern:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludeDevtools>false</excludeDevtools> </configuration> </plugin> </plugins> </build>
Oder mit gradle musst du
excludeDevtools = false setzen :
bootWar { excludeDevtools = false }
Anschließend müssen Sie ein Kennwort festlegen, das für die Authentifizierung beim Herstellen einer Verbindung mit der Remoteanwendung verwendet wird:
spring.devtools.remote.secret=somesecret
Stellen Sie eine Verbindung zu einer Remoteanwendung her
Nach dem Starten der Remoteanwendung können Sie die Remoteverbindungssitzung starten. Jetzt müssen Sie nur noch
org.springframework.boot.devtools.RemoteSpringApplication mit der URL Ihrer Remote-Anwendung als Argument
ausführen . Bitte beachten Sie, dass Sie nach Möglichkeit
https verwenden sollten.
Das Starten einer Remoteverbindung ist in Ihrer IDE einfach. In IDEA müssen Sie lediglich eine neue Startkonfiguration erstellen. Gehen Sie zu
Ausführen → Konfigurationen bearbeiten ... und erstellen Sie eine neue Konfiguration mit dem Symbol
+ in der oberen linken Ecke. Wählen Sie einen Anwendungstyp.
Wählen Sie für die Main-Klasse
RemoteSpringApplication im DevTools-Modul aus und übergeben Sie die URL Ihrer Remote-Anwendung als Argument an das Programm.

Nach dem Start dieser Konfiguration sollte eine ähnliche Ausgabe angezeigt werden, wenn die Verbindung zur Remoteanwendung erfolgreich war.

Nach dem Herstellen einer Verbindung zu einer Remoteanwendung überwacht DevTools die Klassenpfadänderungen auf dieselbe Weise wie bei der lokalen Entwicklung. Anstelle eines lokalen Neustarts werden jedoch die Änderungen auf den Remote-Server übertragen und dort ein Neustart eingeleitet. Dies kann viel schneller sein als das Erstellen einer Anwendung und das Bereitstellen auf einem Remotecomputer.
Globale Konfiguration
Sie können DevTools wie jede andere Spring-Anwendung mithilfe von Konfigurationseigenschaften anpassen. Dies bedeutet normalerweise, dass Sie die
application.properties Ihres Projekts bearbeiten. Diese Konfiguration ist für jede Anwendung unterschiedlich.
In einigen Szenarien kann es jedoch zweckmäßig sein, eine globale Konfiguration für ALLE Anwendungen zu haben, die auf demselben Computer ausgeführt werden. Sie können eine Eigenschaftendatei mit dem Namen
.spring-boot-devtools.properties in Ihrem
$ HOME- Verzeichnis erstellen. Die in dieser Datei angegebene Erklärung gilt für alle Anwendungen, die DevTools verwenden.
Einschränkungen
Live nachladen
Eine Spring-Anwendung, die DevTools verwendet, startet automatisch den LiveReload-Server. Leider kann immer nur eine Instanz dieses Servers gestartet werden. Genauer gesagt funktioniert nur die erste Instanz. Dies gilt nicht nur für mehrere Instanzen von Spring-Anwendungen mit DevTools, sondern auch für alle anderen Anwendungen, die LiverReload unter der Haube verwenden, z. B.
Gatsby im Entwicklungsmodus.
Wenn Sie die Spring-Anwendung so konfigurieren möchten, dass der LiveReload-Server nicht gestartet wird, können Sie dies in der Datei
application.properties tun:
spring.devtools.livereload.enabled=false
Haken zum Herunterfahren
DevTools hängen vom
Shutdown-Hook- Attribut der
SpringApplication- Klasse ab. Die Klasse wird nicht korrekt funktionieren, wenn Sie das Attribut manuell deaktiviert haben:
springApplication.setRegisterShutdownHook(false);
Das Attribut ist standardmäßig aktiviert, sodass Sie sich darüber keine Gedanken machen müssen, es sei denn, Sie deaktivieren es ausdrücklich.
Kollisionen mit Bibliotheken von Drittanbietern
Obwohl DevTools normalerweise ordnungsgemäß funktionieren sollte, kann es zu Konflikten mit Bibliotheken von Drittanbietern kommen. Insbesondere ist ein Problem bei der Deserialisierung mit dem Standard-
ObjectInputStream bekannt .
In einem solchen Konflikt können Sie den automatischen Neustart deaktivieren, indem Sie Folgendes festlegen:
spring.devtools.restart.enabled=false
Neustart funktioniert nicht mehr. Der
Neustart- Classloader wird jedoch weiterhin verwendet. Wenn Sie das Klassenladeprogramm vollständig deaktivieren müssen, müssen Sie dies tun, bevor Sie die Anwendung starten:
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
Auch wenn Sie keinen automatischen Neustart verwenden, können Sie andere DevTools-Funktionen verwenden.
Aktivieren der verzögerten Initialisierung
Sie können einzelne Komponenten mithilfe von Anmerkungen als träge initialisiert markieren
. Diese Funktion ist seit geraumer Zeit verfügbar. Ab Spring Boot 2.2 können Sie die verzögerte Initialisierung für alle Bean-Komponenten mit
spring.main.lazy-initialization = true umschalten .
Dies kann alleine oder
in Kombination mit DevTools für einen noch schnelleren Neustart verwendet werden .
Mit DevTools können Sie Ihre Anwendung in derselben JVM im laufenden Betrieb neu starten. Ein wesentlicher Vorteil eines Warmstarts besteht darin, dass JIT mehr Optionen zur Optimierung des zum Starten Ihrer Anwendung verwendeten Codes bietet. Nach mehreren Neustarts verringert sich die Anfangszeit von 2500 ms um fast 80% und nähert sich 500 ms. Mit der verzögerten Initialisierung können wir bessere Ergebnisse erzielen. Bei der Installation von
spring.main.lazy-initialization wird unsere Anwendung nach 400 ms direkt in der IDE neu
gestartet .
Die Verwendung der verzögerten Initialisierung für alle Ihre Beans in einer Produktionsanwendung ist zweifelhaft. Diese Prozedur bietet überlegene Leistungssteigerungen beim Start aufgrund längerer Anforderungen beim ersten Mal an einzelne Bean-Komponenten. Noch wichtiger ist, dass Ihre Anwendung nicht aufhört, schnell zu arbeiten. Anstatt jedoch sofort nach dem Start der Anwendung zum Absturz zu bringen, schlägt dies erst nach direkter Anforderung der falsch konfigurierten Komponente fehl. Dies kann sehr gefährlich sein, da Sie erst dann viele Fehler finden, wenn es zu spät ist. Eine massenverzögerte Initialisierung kann jedoch hilfreich sein, um die Entwicklungszeit zu verkürzen, da Sie bei der Arbeit mit einer bestimmten Funktion normalerweise nur einen Teil Ihrer Anwendung bearbeiten und den Rest nicht verwenden. Der ideale Kompromiss wäre, die massenverzögerte Initialisierung nur für die lokale Entwicklung zu aktivieren (z. B. mithilfe eines Federprofils) und sie für höhere Umgebungen zu deaktivieren.
Fazit
DevTools beschleunigt und vereinfacht die Entwicklung von Spring Boot-Anwendungen, indem ein automatischer Neustart und LiveReload-Funktionen bereitgestellt werden. Darüber hinaus werden verschiedene Eigenschaften für Werte festgelegt, die für die lokale Entwicklung besser geeignet sind. Darüber hinaus können Sie eine Remoteverbindung zu Ihrer Anwendung herstellen und gleichzeitig die meisten Funktionen nutzen. Beim Starten der Anwendung in der Produktion werden DevTools nicht verwendet. Einzelheiten finden Sie in der
offiziellen Dokumentation .