Spring Boot Tutorial
Spring Boot DevTools
The development loop — change code, restart, check the result — happens hundreds of times a day. If each restart takes ten seconds and a manual click, that adds up quickly. Spring Boot DevTools shortens the loop: it restarts your application automatically when classes change, disables template caching, applies development-friendly defaults, and can even update an application running remotely.
This lesson explains how the automatic restart works, how to use it in IntelliJ IDEA, Eclipse and VS Code, which property defaults DevTools changes, how to exclude files from triggering restarts, and why DevTools is never included in production builds.
Adding DevTools
Add spring-boot-devtools as an optional dependency (Maven) or developmentOnly configuration (Gradle). DevTools disables itself automatically when the application is launched from a fully packaged jar (java -jar) and the build plugins exclude it from the final artifact, so it cannot leak into production.
How Automatic Restart Works
DevTools uses two class loaders. Libraries that do not change (Spring, Hibernate, Jackson) are loaded once by a base class loader. Your own classes are loaded by a restart class loader. When files on the classpath change, DevTools throws away only the restart class loader and creates a new one, which is much faster than a cold start. A restart is triggered when compiled class files change — so your IDE must compile on save (automatic in Eclipse and VS Code; in IntelliJ enable "Build project automatically" and "Allow auto-make to start even if developed application is currently running").
Development Property Defaults
DevTools sets defaults that suit development but not production: template caching is disabled for Thymeleaf, FreeMarker and Mustache; web request logging is more detailed (spring.mvc.log-request-details); error pages include more information. These defaults apply only when DevTools is active, so you do not need a separate profile for them.
Excluding Resources and Triggers
Changes to static resources and templates do not need a restart — the browser simply reloads them. By default files under /static, /public, /templates and /META-INF/resources do not trigger restarts. Use spring.devtools.restart.exclude or additional-exclude to add more, spring.devtools.restart.trigger-file to restart only when a specific file changes (useful if your IDE compiles continuously), and spring.devtools.restart.enabled=false to switch restarts off.
When Restarts Are Not Enough
Restarts keep the JVM but rebuild the Spring context, so in-memory state (sessions, caches, H2 data) is lost. For instant method-body changes without any restart, run the app in debug mode and use your IDE's hot swap, or a tool such as JRebel. Some libraries that cache class loaders (certain serializers) can misbehave after restarts; exclude their jars from the restart class loader with META-INF/spring-devtools.properties.
Examples
Adding DevTools with Maven and Gradle
<!-- Maven -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
// Gradle (Kotlin DSL)
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
Run with mvn spring-boot:run or from the IDE:
... Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
... For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
Watching a restart happen after editing a controller
@RestController
public class GreetingController {
@GetMapping("/greet")
public String greet() {
return "Hello from Webnest v2"; // edited and saved while the app is running
}
}
(save file → IDE compiles → DevTools detects change)
... Restarting due to 1 class path change (0 additions, 0 deletions, 1 modification)
... Started WebnestAppApplication in 0.412 seconds (process running for 95.7)
curl http://localhost:8080/greet
Hello from Webnest v2
Tuning restart behaviour
# application.yml
spring:
devtools:
restart:
additional-exclude: "docs/**,generated/**" # don't restart when these change
poll-interval: 2s
quiet-period: 1s
# trigger-file: .reloadtrigger # restart only when this file is touched
(Editing src/main/resources/docs/readme.md no longer restarts the application.)
Common Mistakes
- Adding DevTools without optional/developmentOnly, so it ends up as a normal dependency of other modules.
- Expecting restarts in IntelliJ without enabling automatic build; DevTools only reacts to compiled class changes.
- Relying on in-memory data (H2, caches) that disappears on every restart and assuming the code is broken.
- Thinking DevTools makes the production app slower — it is disabled for packaged jars and excluded from the build.
- Putting frequently regenerated files on the classpath, causing endless restart loops.
Key Points to Remember
- spring-boot-devtools gives automatic restarts and development-friendly defaults.
- Two class loaders make restarts far faster than a cold start.
- Restarts are triggered by compiled class changes; enable build-on-save in your IDE.
- Static files and templates do not trigger restarts; configure exclusions and trigger files as needed.
- DevTools is automatically disabled in packaged jars and excluded from production builds.
Practice the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Use your local JDK or project IDE for these examples. Codelab currently runs Python and HTML/CSS/JavaScript; framework examples may need project dependencies.