Developer Tools & Hot Reload
Developer Tools & Hot Reload
Every second you spend waiting for a full JVM restart is a second stolen from actual development. Spring Boot's spring-boot-devtools module attacks that problem from several angles: automatic class reloading, live configuration refresh, a persistent HTTP session between restarts, and a sensible set of development-friendly defaults — all without touching your production build.
Adding DevTools to Your Project
DevTools ships as a standard starter. Add it to pom.xml:
Or in Gradle (build.gradle):
optional / developmentOnly? Spring Boot's repackage goal automatically excludes all optional and developmentOnly dependencies from the executable fat-JAR. DevTools will never end up on the production classpath — zero risk of accidentally enabling restart behaviour in a live environment.
Automatic Restart — How It Works
DevTools watches the files on your classpath. The moment it detects a change — a recompiled .class file, a modified .properties or template — it triggers an application restart. The key insight is that it uses two ClassLoaders:
- Base ClassLoader — loads third-party JARs (Spring, Hibernate, libraries). These change rarely, so the base ClassLoader is not discarded between restarts. It is created once and kept alive.
- Restart ClassLoader — loads your own application code (the classes in
target/classes). This one is discarded and recreated on every restart.
Because two-thirds of the JVM startup cost (loading and initialising third-party bytecode) is eliminated, the effective restart time is typically 1–3 seconds instead of 10–20 seconds for a clean JVM boot.
Configuring the Watch Paths
By default DevTools monitors everything on the classpath. You can tune this in application.properties:
Excluding static/** and templates/** is a common optimisation: changing a Thymeleaf template or a CSS file does not require a JVM-level restart — a plain browser refresh is enough. Keeping those paths out of the restart trigger makes the cycle faster still.
LiveReload Integration
DevTools embeds a LiveReload server on port 35729. Install the free LiveReload browser extension (Chrome/Firefox/Safari) and your browser will automatically refresh the current page after each restart. For template and static-asset changes that did not trigger a restart, DevTools still sends the reload signal.
spring.devtools.livereload.port=<other-port> and update the LiveReload extension settings to match.
Remote DevTools
DevTools can also connect to a remote application — a staging server running the devtools JAR — and push restart triggers over HTTP. This is useful in Docker-based workflows where you edit locally but run in a container.
Enable remote support in the application you are deploying (not recommended for public internet, only internal / VPN-protected hosts):
Then run the RemoteSpringApplication launcher locally, pointing it at the remote URL. Every time you recompile locally, the changed classes are uploaded and the remote server restarts within seconds.
Development-Time Property Overrides
DevTools automatically applies a set of sensible defaults when it detects a development environment. Notable overrides include:
- Thymeleaf caching disabled (
spring.thymeleaf.cache=false) — template changes are visible immediately. - FreeMarker, Groovy, Mustache, and web MVC caching also disabled.
- Logging level for web group set to
DEBUGso request mappings, handler execution, and view resolution appear in the console. - H2 console enabled if you have H2 on the classpath.
You can inspect the full list in DevToolsPropertyDefaultsPostProcessor in the Spring Boot source. These overrides are applied via a lowest-precedence PropertySource, so any value you explicitly set in application.properties takes priority.
Persisting Sessions Across Restarts
By default DevTools serialises the HTTP session to disk before a restart and deserialises it afterwards. This means you stay logged in through every restart cycle — no more re-authenticating after every save. You can opt out:
Global DevTools Settings
If you work across multiple projects and want a single shared DevTools configuration, create a file at ~/.config/spring-boot/spring-boot-devtools.properties (Spring Boot 2.3+) or the legacy path ~/.spring-boot-devtools.properties. Settings here apply to all DevTools-enabled projects on the machine:
The trigger file pattern is especially useful in IDEs that continuously compile: instead of restarting on every individual class-file change, DevTools only restarts when a specific file (e.g. .trigger) is touched. This prevents partial restarts during multi-file compilations.
DevTools vs JRebel vs Spring Loaded
DevTools is free, zero-configuration, and sufficient for the vast majority of projects. JRebel is a commercial product that hot-swaps classes without restarting the Spring context — useful for very large applications where even a 2-second restart disrupts flow. Spring Loaded is an open-source predecessor that is now largely superseded by DevTools. For most teams, DevTools hits the sweet spot.
Summary
spring-boot-devtools compresses the inner development loop from a 15-second full restart to a 1–3 second context reload using a dual-ClassLoader strategy. Pair it with IDE auto-compilation and the LiveReload browser extension and you get a near-instantaneous feedback cycle. Mark the dependency optional (Maven) or developmentOnly (Gradle) and it will never reach your production fat-JAR. In the next and final lesson you will bring everything together by building your first complete Spring Boot application from scratch.