Spring Boot contains an additional set of tools that can make the application development process a little more
enjoyable. The spring-boot-devtools
module can be added to any project to provide additional
functionality during development. To implement devtools support, add a module dependency to your build, as shown in
the following listings for Maven and Gradle:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
dependencies {
developmentOnly("org.springframework.boot:spring- boot-devtools")
}
java -jar
or a custom class loader, then it is
considered a "production application". You can control this operating logic using the spring.devtools.restart.enabled
system property. To enable devtools regardless of the class loader used to start the application, set the system
property -Dspring.devtools.restart.enabled=true
. This should not be done in a production environment
where running devtools poses a security risk. To disable devtools, exclude the dependency or set the system property
-Dspring.devtools.restart.enabled=false
.
developmentOnly
configuration in Gradle (as shown above), this will prevent devtools from being
transitively applied to other modules using your project.
excludeDevtools
property to
false
. When using the Gradle plugin, configure the classpath for the task to contain the developmentOnly
configuration.
Diagnosing class loading problems
Restart functionality has been implemented using two class loaders. For most applications this approach works well. However, it can sometimes lead to class loading problems, especially in multi-module projects.
To diagnose whether class loading problems are actually caused by devtools and its two class loaders, try disabling restart. If this solves your problems, set the class loader restart to cover your entire project.
Default properties
Some libraries supported by Spring Boot use caches to improve performance. For example, template engines cache compiled templates to avoid repeatedly parsing template files. Additionally, Spring MVC can add HTTP caching headers to responses when processing static resources.
While caching is very useful in a production environment, it can be counterproductive during development, preventing you from seeing changes that have just been made included in the application. For this reason, spring-boot-devtools disables caching settings by default.
Cache settings are typically configured using settings in the application.properties
file. For example, Thymeleaf provides a spring.thymeleaf.cache
property. Instead of setting these
properties manually, the spring-boot-devtools
module automatically applies the appropriate
configuration during development.
The following table lists all the applied properties:
Name | Default value |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
spring.devtools.add-properties
to
false
in the file application.properties
.
Because development of Spring MVC and
Spring WebFlux applications requires more information about web requests, the development tools suggest enabling
DEBUG
logging for web
-logging groups. This will give information about the incoming
request, which handler is processing it, the result of the response, and other details. If you want to log all
request details (including potentially sensitive information), you can enable the spring.mvc.log-request-details
or spring.codec.log-request-details
.
Automatic restart
Applications using spring-boot-devtools
are automatically restarted when files in the classpath are
changed. This can be a useful feature when working in an IDE as it provides very fast feedback for making changes to
the code. By default, any entry in the classpath that points to a directory is monitored for changes. Please note
that some resources, such as static content and view templates, do not require an application restart.
forking
set to
enabled
. If you disable forking, the application's isolated class loader used by devtools will not be
created and restarting will not work as expected.
SpringApplication.setRegisterShutdownHook(false)
).
ResourceLoader
used by
ApplicationContext
. If your application already provides such a loader, it will be wrapped. Direct
overriding of the getResource
method on ApplicationContext
is not supported.
Log changes to state calculation
By default every time When the application is restarted, a report is logged showing the state calculation delta. The report shows changes to your application's autoconfiguration as you make changes, such as adding or removing beans and setting configuration properties.
To disable reporting logging, set the following property:
spring.devtools.restart.log-condition-evaluation-delta=false
spring:
devtools:
restart:
log-condition-evaluation-delta: false
Resource exclusion
Some resources do not necessarily need to trigger a reload when they change. For
example, Thymeleaf templates can be edited in the same place. By default, changing resources in /META-INF/maven
,
/META-INF/resources
, /resources
, /static
, /public
or /templates
does not trigger a restart, but does trigger a real-time reload. If you want to configure these exceptions, you can
use the spring.devtools.restart.exclude
property. For example, to exclude only /static
and
/public
, you would set the following property:
spring.devtools.restart.exclude=static/**,public/**
spring:
devtools:
restart:
exclude: "static/**,public/**"
spring.devtools.restart.additional-exclude property
.
Tracking additional paths
You may want the application to restart or reload after making changes to
files that are not in the classpath. To do this, use the spring.devtools.restart.additional-paths
property to configure additional paths for change tracking. You can use the
spring.devtools.restart.exclude
property to control whether changes to additional paths will trigger a
full restart or a real-time restart.
Disabling restart
If you do not need to use the restart
feature, you can disable it using the spring.devtools.restart.enabled
property. In most cases, you can
set this property in the application.properties
file (this will still initialize the restarting
classloader, but file changes will not be tracked).
If required completely disable restart support
(for example, because it does not work with a certain library), then before calling
SpringApplication.run(…)
you need to set the System
for spring.devtools.restart.enabled
to false
, as shown in the following example:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApplication.class, args);
}
}
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication
object MyApplication {
@JvmStatic
fun main(args: Array<String>) {
System.setProperty("spring.devtools.restart.enabled", "false")
SpringApplication.run(MyApplication::class.java, *args)
}
}
Using a trigger file
If you are working with an IDE that constantly compiles files that change, you may prefer to trigger a reload only at certain times. To do this, you can use a "trigger file", which is a specialized file that needs to be modified if you actually want to trigger the restart check.
To use a trigger file, set the property spring.devtools.restart.trigger-file
to the name
(excluding path) of your trigger file. The trigger file should be somewhere in your classpath.
For example, if you have a project with the following structure:
src +- main +- resources +- .reloadtrigger
Then the property of your trigger-file
will be like this:
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger "
Restart will now only occur when updating src/main/resources/.reloadtrigger
.
spring.devtools.restart.trigger-file
as a
global setting so that all your projects have the same logic.
Some IDEs have features that eliminate the need to manually update the trigger file. Spring Tools for Eclipse and IntelliJ IDEA (Ultimate Edition) has such support
tools. In Spring Tools, you can use the "reload" button from the console view (assuming your
trigger-file
is named .reloadtrigger
). For IntelliJ IDEA, you can follow instructions
in the relevant documentation.
Configuring a restarting class loader
The restart functionality is implemented through two class loaders. If any problems arise, you may need to configure what is loaded with which class loader.
By default, any open project in your IDE is loaded with a "restart" class
loader, and any regular. The jar
file is loaded with the "main" class loader. The same is true if
mvn spring-boot:run
or gradle bootRun
is used: a project containing the @SpringBootApplication
annotation is loaded with "restart" the class loader, and everything else with the "main" class loader.
You
can tell Spring Boot to load project components with a different class loader by creating a file META-INF/spring-devtools.properties
.
The spring-devtools.properties
file may contain properties with the prefixes
restart.exclude
and restart.include
. include
elements are components that need to be pushed up into the
"restarting" classloader, and exclude
elements are elements that need to be pushed down into the "main"
classloader. The property value is a regular expression pattern that is applied to the classpath, as shown in the
following example:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\ \.jar
restart:
exclude:
companycommonlibs: "/mycorp-common-[\\w\\d-\\.]+\\.jar"
include:
projectcommon: "/mycorp-myproj-[\\w\\d-\\.]+\\.jar "
restart.include.
or restart.exclude.
, then it is taken into account.
META-INF/spring-devtools.properties
from the classpath. You can package files within your project or in
libraries that the project uses.
Known limitations
The restart functionality does not work very well with objects that are deserialized using
the standard ObjectInputStream
. If you need to deserialize data, you may need to use ConfigurableObjectInputStream
from Spring in combination with Thread.currentThread().getContextClassLoader()
.
Unfortunately, some Third-party libraries deserialize without taking into account the context class loader. If you encounter such a problem, you will need to request a fix from the creators.
LiveReload
The spring-boot-devtools
module contains a built-in LiveReload server, which can be used to trigger a browser refresh when a resource
changes. LiveReload browser extensions for Chrome, Firefox and Safari are freely available at livereload.com.
If you do not need to
start the LiveReload server when running the application, you can set the
spring.devtools.livereload.enabled
property to false
.
Global Settings
You can configure devtools global settings by adding any of the following files to
the $HOME/.config/spring-boot
directory:
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
Any properties added to These files apply to all Spring Boot applications on your machine that use
devtools. For example, to configure restart to always use a trigger file, you would add the following property to
the spring-boot-devtools
file:
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
Default $HOME
is the user's home directory. To configure this location, set the SPRING_DEVTOOLS_HOME
environment variable or the spring.devtools.home
system property.
$HOME/.config/spring-boot
,
the root of the $HOME
directory will be searched for the presence of a file .spring-boot-devtools.properties
.
This will allow the global devtools configuration to be shared with
applications that run on an older version of Spring Boot that does not support the
$HOME/.config/spring-boot
location.
Profiles are not supported in properties/yaml files for devtools.
Any profiles enabled in .spring-boot-devtools.properties
, will not affect the download of files
associated with a specific profile. Profile-specific file names (like spring-boot-devtools-<profile>.properties
)
and spring.config.activate.on-profile
documents in YAML files and Properties are not supported.
Configuring a file system watcher
FileSystemWatcher is working by polling for class changes at certain time intervals and then
waiting for a predefined period of inactivity to ensure that there are no more changes. Because Spring Boot relies
entirely on the IDE to compile and copy files to a location where Spring Boot can read them, you may experience some
changes not being reflected when you restart your application using devtools. If you experience problems like this
consistently, try increasing the spring.devtools.restart.poll-interval
and spring.devtools.restart.quiet-period
settings to values that match your development environment:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period= 1s
spring:
devtools:
restart:
poll-interval : "2s"
quiet-period: "1s"
Monitored classpath directories are now polled every 2 seconds for changes, and a 1 second quiet period is observed, to ensure that there are no additional changes to classes.
Remote applications
Spring Boot developer tools are not limited to local development. You can also use several features when running applications remotely. Remote work support tools are optional because their activation may pose a security risk. They should only be enabled when working on a trusted network or if protected by SSL. If none of these options are available, you should not use the remote support tools for DevTools. Under no circumstances should you enable support tools during a production deployment.
To enable support, you must ensure that devtools
is included in the
repackaged archive, as shown in the following listing:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
Then you need to set the spring.devtools.remote.secret
property. Like any important password or
sensitive information, the value must be unique and strong so that it cannot be guessed or brute-forced.
The
devtools remote support tools are provided in two parts: a server-side endpoint, connection receiver, and a client
application that you run in your IDE. The server component is automatically activated if the spring.devtools.remote.secret
property is set. The client component must be started manually.
Running a remote client application
The remote client application is designed to run from your IDE.
You must execute org.springframework.boot.devtools.RemoteSpringApplication
with the same classpath as
the remote project you are connecting to. The only required argument to the application is the remote URL to which
it connects.
For example, if you are using Eclipse or Spring Tools and have a project named
my-app
that is deployed to Cloud Foundry, you need to do the following:
Select
Run Configurations…
from theRun
menu.Create a new "launch configuration"
Java Application
.Find the project
my-app
.Use
org.springframework.boot.devtools.RemoteSpringApplication
as the main class.Add
https://myapp.cfapps.io
inProgram arguments
(or whatever your remote access URL is).
The running remote client might look like this:
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \ \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) ) ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / / =========|_|==============|___/===================================/_/_/_/ :: Spring Boot Remote :: (v2.7.5) 2022-10-20 12:40:15.175 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v2.7.5 using Java 1.8.0_345 on myhost with PID 16215 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/2.7.5/spring-boot-devtools-2.7.5.jar started by myuser in /opt/apps/) 2022-10-20 12:40:15.182 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default" 2022-10-20 12:40:15.913 INFO 16215 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2022-10-20 12:40:15.946 INFO 16215 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpri
spring.devtools.remote.secret
property and passes it to the server for authentication.
https://
as a connection
protocol so that traffic is encrypted and passwords cannot be intercepted.
spring.devtools.remote.proxy.host
and spring.devtools.remote.proxy.port
.
Remote update
The remote client monitors changes to your application's classpath in the same way that a local restart program does. Any updated resource is passed to the remote application and (if required) triggers a restart. This can be useful if you are repeating a function that uses a cloud service that is not available locally. In general, a remote upgrade and reboot is much faster than a complete rebuild and deployment.
In a slow development environment, it may be that the idle period is insufficient and changes to classes may be broken up into batches. The server will restart after downloading the first batch of class changes. The next package cannot be sent to the application because the server is being restarted.
This typically results in a warning
in the RemoteSpringApplication
logs that some classes could not be loaded and then retrying . But this
can also result in inconsistent application code and the inability to restart after downloading the first batch of
changes. If you experience problems like this consistently, try increasing the spring.devtools.restart.poll-interval
and spring.devtools.restart.quiet-period
settings to values that match your development environment .
GO TO FULL VERSION