本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
本节更详细地介绍了你应该如何使用Spring Boot。 它涵盖了诸如构建系统、自动配置、以及如何运行你的应用程序等主题。 我们还介绍了一些Spring Boot的最佳实践。 虽然Spring Boot没有什么特别之处(它只是另一个你可以使用的库),但有一些建议,如果遵循这些建议,可以使你的开发过程更容易一些。
如果你刚开始使用Spring Boot,在进入本节之前,你应该先阅读 入门 指南。
1. 构建系统
强烈建议你选择一个支持依赖管理的构建系统,并且它可以从 “Maven Central” 拉取依赖。我们建议你选择Maven或Gradle。选择其他构建系统(例如Ant),也不是不行,但它们的支持并不特别好。
1.1. 依赖管理
Spring Boot的每个版本都提供了一个它所支持的依赖的列表。 在实践中,你不需要在构建配置中为这些依赖声明版本,因为Spring Boot会帮你管理这些。 当你升级Spring Boot本身时,这些依赖也会一同升级。
你仍然可以指定某个依赖的版本,来覆盖spring boot默认的版本。 |
这份精心策划依赖清单包含了所有可以在Spring Boot中使用的Spring模块,以及一份第三方库的列表。该列表以依赖( spring-boot-dependencies
)的形式提供,可在Maven和Gradle中使用。
Spring Boot的每个版本都与Spring框架的基本版本有关。 我们 强烈建议 你不要修改Spring的版本。 |
1.4. Ant
可以使用Apache Ant+Ivy来构建Spring Boot项目。
spring-boot-antlib
“AntLib” 模块也可以用来帮助Ant创建可执行的jar。
声明依赖,一个典型的 ivy.xml
文件如下。
<ivy-module version="2.0">
<info organisation="org.springframework.boot" module="spring-boot-sample-ant" />
<configurations>
<conf name="compile" description="everything needed to compile this module" />
<conf name="runtime" extends="compile" description="everything needed to run this module" />
</configurations>
<dependencies>
<dependency org="org.springframework.boot" name="spring-boot-starter"
rev="${spring-boot.version}" conf="compile" />
</dependencies>
</ivy-module>
一个典型的 build.xml
如下。
<project
xmlns:ivy="antlib:org.apache.ivy.ant"
xmlns:spring-boot="antlib:org.springframework.boot.ant"
name="myapp" default="build">
<property name="spring-boot.version" value="3.2.0-SNAPSHOT" />
<target name="resolve" description="--> retrieve dependencies with ivy">
<ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
</target>
<target name="classpaths" depends="resolve">
<path id="compile.classpath">
<fileset dir="lib/compile" includes="*.jar" />
</path>
</target>
<target name="init" depends="classpaths">
<mkdir dir="build/classes" />
</target>
<target name="compile" depends="init" description="compile">
<javac srcdir="src/main/java" destdir="build/classes" classpathref="compile.classpath" />
</target>
<target name="build" depends="compile">
<spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
<spring-boot:lib>
<fileset dir="lib/runtime" />
</spring-boot:lib>
</spring-boot:exejar>
</target>
</project>
如果你不想使用 spring-boot-antlib 模块,请参阅 “How-to” 。
|
1.5. Starter
Starter是一系列开箱即用的依赖,你可以在你的应用程序中导入它们。
通过你Starter,可以获得所有你需要的Spring和相关技术的一站式服务,免去了需要到处大量复制粘贴依赖的烦恼。
例如,如果你想开始使用Spring和JPA进行数据库访问,那么可以直接在你的项目中导入 spring-boot-starter-data-jpa
依赖。
Starter含了很多你需要的依赖,以使项目快速启动和运行,并拥有一套一致的、受支持的可管理的过渡性依赖。
以下是Spring Boot在 org.springframework.boot
这个 groupId
下提供的starter组件。
Name | Description |
---|---|
Core starter, including auto-configuration support, logging and YAML |
|
Starter for JMS messaging using Apache ActiveMQ |
|
Starter for using Spring AMQP and Rabbit MQ |
|
Starter for aspect-oriented programming with Spring AOP and AspectJ |
|
Starter for JMS messaging using Apache Artemis |
|
Starter for using Spring Batch |
|
Starter for using Spring Framework’s caching support |
|
Starter for using Cassandra distributed database and Spring Data Cassandra |
|
Starter for using Cassandra distributed database and Spring Data Cassandra Reactive |
|
Starter for using Couchbase document-oriented database and Spring Data Couchbase |
|
Starter for using Couchbase document-oriented database and Spring Data Couchbase Reactive |
|
Starter for using Elasticsearch search and analytics engine and Spring Data Elasticsearch |
|
Starter for using Spring Data JDBC |
|
Starter for using Spring Data JPA with Hibernate |
|
Starter for using Spring Data LDAP |
|
Starter for using MongoDB document-oriented database and Spring Data MongoDB |
|
Starter for using MongoDB document-oriented database and Spring Data MongoDB Reactive |
|
Starter for using Neo4j graph database and Spring Data Neo4j |
|
Starter for using Spring Data R2DBC |
|
Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client |
|
Starter for using Redis key-value data store with Spring Data Redis reactive and the Lettuce client |
|
Starter for exposing Spring Data repositories over REST using Spring Data REST and Spring MVC |
|
Starter for building MVC web applications using FreeMarker views |
|
Starter for building GraphQL applications with Spring GraphQL |
|
Starter for building MVC web applications using Groovy Templates views |
|
Starter for building hypermedia-based RESTful web application with Spring MVC and Spring HATEOAS |
|
Starter for using Spring Integration |
|
Starter for using JDBC with the HikariCP connection pool |
|
Starter for building RESTful web applications using JAX-RS and Jersey. An alternative to |
|
Starter for using jOOQ to access SQL databases with JDBC. An alternative to |
|
Starter for reading and writing json |
|
Starter for using Java Mail and Spring Framework’s email sending support |
|
Starter for building web applications using Mustache views |
|
Starter for using Spring Authorization Server features |
|
Starter for using Spring Security’s OAuth2/OpenID Connect client features |
|
Starter for using Spring Security’s OAuth2 resource server features |
|
Starter for using the Quartz scheduler |
|
Starter for building RSocket clients and servers |
|
Starter for using Spring Security |
|
Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito |
|
Starter for building MVC web applications using Thymeleaf views |
|
Starter for using Java Bean Validation with Hibernate Validator |
|
Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container |
|
Starter for using Spring Web Services |
|
Starter for building WebFlux applications using Spring Framework’s Reactive Web support |
|
Starter for building WebSocket applications using Spring Framework’s MVC WebSocket support |
除了应用starter外,以下启动器可用于添加 生产就绪 功能。
Name | Description |
---|---|
Starter for using Spring Boot’s Actuator which provides production ready features to help you monitor and manage your application |
最后,Spring Boot还包括以下starter,如果你想排除或更换特定的技术实现,那么可以使用它们。
Name | Description |
---|---|
Starter for using Jetty as the embedded servlet container. An alternative to |
|
Starter for using Log4j2 for logging. An alternative to |
|
Starter for logging using Logback. Default logging starter |
|
Starter for using Reactor Netty as the embedded reactive HTTP server. |
|
Starter for using Tomcat as the embedded servlet container. Default servlet container starter used by |
|
Starter for using Undertow as the embedded servlet container. An alternative to |
有关其他社区贡献的starter列表,请参见GitHub上 spring-boot-starters 模块的 README 文件。
|
2. 代码结构
Spring Boot对代码的布局,没有特别的要求。 但是,有一些最佳实践。
2.1. “default” 包
当一个类不包括 package
的声明时,它被认为是在 “default package” 中。
通常应避免使 “default package”。
对于使用了 @ComponentScan
, @ConfigurationPropertiesScan
, @EntityScan
或者 @SpringBootApplication
注解的Spring Boot应用程序来说,它可能会造成一个问题:项目中的所有jar里面的所有class都会被读取(扫描)。
我们建议你遵循Java推荐的包的命名惯例,使用域名反转作为包名(例如, com.example.project )。
|
2.2. 启动类的位置
我们通常建议你将你启动类放在一个根package中,高于其他的类,@SpringBootApplication
注解一般都是注解在启动类上的。它默认会扫描当前类下的所有子包。例如,如果你正在编写一个JPA应用程序,你的 @Entity
类只有定义在启动类的子包下才能被扫描加载到。这样的好处也显而易见,@SpringBootApplication
默认只会扫描加载你项目工程中的组件。
如果你不想使用 @SpringBootApplication ,它所导入的 @EnableAutoConfiguration 和 @ComponentScan 注解定义了该行为,所以你也可以使用这些来代替。
|
一个项目典型的布局如下。
com +- example +- myapplication +- MyApplication.java | +- customer | +- Customer.java | +- CustomerController.java | +- CustomerService.java | +- CustomerRepository.java | +- order +- Order.java +- OrderController.java +- OrderService.java +- OrderRepository.java
MyApplication.java
文件声明了 main
方法,以及标识了基本的 @SpringBootApplication
注解,如下所示。
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
3. Configuration 类
Spring Boot倾向于通过Java代码来进行配置的定义。
虽然也可以使用XML来配置 SpringApplication
,但还是建议你通过 @Configuration
类来进行配置。
通常,可以把启动类是作为主要的 @Configuration
类。
网上有很多关于“通过XML配置Spring”的示例,如果可以的话,还是尽量使用Java代码的方式来实现相同的配置。你可以尝试着搜索 Enable* 注解。
|
4. 自动装配(配置)
Spring Boot的自动装配机制会试图根据你所添加的依赖来自动配置你的Spring应用程序。
例如,如果你添加了 HSQLDB
依赖,而且你没有手动配置任何DataSource Bean,那么Spring Boot就会自动配置内存数据库。
你需要将 @EnableAutoConfiguration
或 @SpringBootApplication
注解添加到你的 @Configuration
类中,从而开启自动配置功能。
你应该只添加一个 @SpringBootApplication 或 @EnableAutoConfiguration 注解。
建议添加到主要的 @Configuration 类上。
|
4.1. 逐步取代自动配置
自动配置是非侵入性的。
在任何时候,你都可以开始定义你自己的配置来取代自动配置的特定部分。
例如,如果你添加了你自己的 DataSource
bean,默认的嵌入式数据库支持就会“退步”从而让你的自定义配置生效。
如果你想知道在应用中使用了哪些自动配置,你可以在启动命令后添加 --debug
参数。
这个参数会为核心的logger开启debug级别的日志,会在控制台输出自动装配项目以及触发自动装配的条件。
4.2. 禁用指定的自动装配类
如果你想禁用掉项目中某些自动装配类,你可以在 @SpringBootApplication
注解的 exclude
属性中指定,如下例所示。
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class MyApplication {
}
@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
class MyApplication
如果要禁用的自动装配类不在classpath上(没有导入),那么你可以在注解的 excludeName
属性中指定类的全路径名称。 exclude
和 excludeName
属性在 @EnableAutoConfiguration
中也可以使用。
最后,你也可以在配置文件中通过 spring.autoconfigure.exclude[]
配置来定义要禁用的自动配置类列表。
你可以同时使用注解 + 配置的方式来禁用自动装配类。 |
自动配置类一般都是 public 的,除了这个类的名称以外(用来禁用它)的任何东西,例如它的方法和属性,包括嵌套的配置类。都不建议你去使用。
|
5. Spring Bean 和 依赖注入
你可以使用任何标准的Spring技术来定义你的Bean以及依赖注入关系。
推荐使用构造函数注入,并使用 @ComponentScan
注解来扫描Bean。
如果你按照上面的建议构造你的代码(将你的启动类定位在顶级包中),你可以在启动类添加 @ComponentScan
注解,也不需要定义它任何参数,
你的所有应用组件(@Component
、@Service
、@Repository
、@Controller
和其他)都会自动注册为Spring Bean。
也可以直接使用 @SpringBootApplication
注解(该注解已经包含了 @ComponentScan
)。
下面的例子展示了一个 @Service
Bean,它使用构造器注入的方式注入了 RiskAssessor
Bean。
@Service
public class MyAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public MyAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
@Service
class MyAccountService(private val riskAssessor: RiskAssessor) : AccountService
如果一个Bean有多个构造函数,你需要用 @Autowired
注解来告诉Spring该用哪个构造函数进行注入。
@Service
public class MyAccountService implements AccountService {
private final RiskAssessor riskAssessor;
private final PrintStream out;
@Autowired
public MyAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
this.out = System.out;
}
public MyAccountService(RiskAssessor riskAssessor, PrintStream out) {
this.riskAssessor = riskAssessor;
this.out = out;
}
// ...
}
@Service
class MyAccountService : AccountService {
private val riskAssessor: RiskAssessor
private val out: PrintStream
@Autowired
constructor(riskAssessor: RiskAssessor) {
this.riskAssessor = riskAssessor
out = System.out
}
constructor(riskAssessor: RiskAssessor, out: PrintStream) {
this.riskAssessor = riskAssessor
this.out = out
}
// ...
}
上面示例中通过构造器注入的 riskAssessor 字段被标识为了 final ,表示一旦Bean创建这个字段就不被改变了。这也是我们推荐的做法。
|
6. 使用 @SpringBootApplication 注解
许多Spring Boot开发者希望他们的应用程序能够使用自动配置、组件扫描,并且能够在他们的 "application class "上定义额外的配置。
一个 @SpringBootApplication
注解就可以用来启用这三个功能,如下。
// Same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
// same as @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootApplication
class MyApplication
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
@SpringBootApplication 也提供了属性别名来定制 @EnableAutoConfiguration 和 @ComponentScan 中的属性。
|
这些功能都不是强制必须的,你可以随时只使用其中任意功能的注解。 例如,你不需要在你的应用程序中使用组件扫描或配置属性扫描。 Java
Kotlin
在这个例子中, |
7. 运行你的应用
把应用打包成可执行jar,并且使用嵌入式HTTP服务器的最大优势,就是可以像其他程序一样运行应用。
该样本适用于调试Spring Boot应用程序。 你不需要任何特殊的IDE插件或扩展。
本节只涉及基本的jar打包。 如果你选择将你的应用程序打包成war文件,请参阅你所使用的Server和IDE的文档。 |
7.1. 在IDE中运行应用
你可以在IDE中像运行普通Java程序一样运行你的Spring Boot应用。
不过,你首先需要导入你的项目。
不同的IDE导入方式可能不同,
大多数IDE可以直接导入Maven项目。
例如,Eclipse用户可以从 File
菜单中选择 Import…
→ Existing Maven Projects
。
如果你不小心把一个Web应用程序运行了两次,你会看到 “Port already in use” 这个异常提示。
Spring Tools用户可以使用 Relaunch 按钮而不是 Run 按钮来实现“重启”(如果程序已经在运行,那么会先关闭它再启动)。
|
7.2. 运行打包后的应用
如果你使用Spring Boot的Maven或Gradle插件来创建可执行jar,你可以使用 java -jar
来运行你的打包后应用程序,如下例所示。
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
打包后的jar程序,也支持通过命令行参数开启远程调试服务,如下。
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar
7.3. 使用 Maven 插件
Spring Boot Maven 插件包括一个 run
目标(goal),可用于快速编译和运行你的应用程序。
应用程序以 exploded
的形式运行,就像在IDE中一样。
运行Spring Boot应用的Maven命令如下。
$ mvn spring-boot:run
如果项目的构建需要消耗很大的内存,你可以考虑使用 MAVEN_OPTS
环境变量来修改最大内存,参考如下。
$ export MAVEN_OPTS=-Xmx1024m
7.4. 使用 Gradle 插件
Spring Boot Gradle插件还包括一个 bootRun
任务,可以用来以 exploded
的形式运行你的应用程序。
只要你应用了了 org.springframework.boot
和 java
插件,就会添加 bootRun
任务,如下例所示。
$ gradle bootRun
同上,如果Gradle构建项目出现内存不足,可以通过 JAVA_OPTS
环境变量来增加JVM的内存。
$ export JAVA_OPTS=-Xmx1024m
7.5. 热部署(Hot Swapping)
由于Spring Boot应用程序是普通的Java应用程序,JVM的热替换功能可以直接使用。但是,JVM的热替换能替换的字节码有限。要想获得更完整的解决方案,可以使用 JRebel 。
spring-boot-devtools
模块提供了快速重启应用程序的支持。详情请见 热部署 “How-to”
8. 开发者工具(Developer Tools)
Spring Boot 提供了一套额外的工具,可以让你更加愉快的开发应用。
spring-boot-devtools
模块可以包含在任何项目中,以在开发期间提供一些有用的特性。
要使用devtools,请添加以下依赖到项目中。
<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")
}
Devtools可能会导致类加载相关的一些问题,特别是在多模块项目中。“ 诊断类加载问题” 解释了如何诊断和解决这些问题。 |
如果你的应用程序是通过 java -jar 启动的,或者是从一个特殊的classloader启动的,那么它就被认为是一个 "生产级别的应用程序",开发者工具会被自动禁用。
你可以通过 spring.devtools.restart.enabled 配置属性来控制这一行为。
要启用devtools,无论用于启动应用程序的类加载器是什么,请设置启动参数 -Dspring.devtools.restart.enabled=true 。
在生产环境中不能这样做,因为运行devtools会有安全风险。
要禁用devtools,请删除该依赖或者设置启动参数 -Dspring.devtools.restart.enabled=false 。
|
应该在Maven中把这个依赖的scope标记为 optional ,或在Gradle中使用 developmentOnly 配置(如上所示)。以防止使用你的项目的其他模块,传递地依赖了devtools。
|
重新打包的压缩文件默认不包含devtools。如果你想使用某个远程devtool功能,,你需要包含它。使用Maven插件时,将 excludeDevtools 属性设为false。使用Gradle插件时, 配置任务的classpath,使其包括 developmentOnly 配置。
|
8.1. 诊断类加载问题
如 重启 Vs 重载 一节所述,重启功能是通过使用两个classloader实现的。 对于大多数应用程序来说,这种方法效果很好。 然而,它有时会导致类加载问题,特别是在多模块项目中。
为了诊断类加载问题是否确实是由devtools和它的两个类加载器引起的,请试着禁用 restart。如果这能解决你的问题,请定制 restart 类加载器 以包括你的整个项目。
8.2. 属性的默认值
在Spring Boot支持的一些库中,会使用缓存来提高性能。例如,模板引擎会缓存已编译的模板,以避免重复解析模板文件。另外,Spring MVC可以在响应静态资源时往响应中添加HTTP缓存头。
虽然缓存在生产中是非常有益的,但在开发过程中可能会产生反作用,使你无法看到你在应用程序中刚做的改动。
由于这个原因,spring-boot-devtools
默认禁用了缓存选项。
缓存的选项通常是通过 application.properties
文件中的属性来配置的。
例如,Thymeleaf提供了 spring.thymeleaf.cache[]
属性。
与其需要手动设置这些属性,spring-boot-devtools
模块会在开发场景下合理的设置这些属性。
下表列出了所有被设置的属性。
Name | Default Value |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
如果你不希望设置属性的默认值,你可以在你的 application.properties 中把 spring.devtools.add-properties[] 设置为 false 。
|
在开发Spring MVC和Spring WebFlux应用程序时,你可能需要更多关于Web请求的信息,开发者工具建议你为Web日志组启用DEBUG日志。这将给你提供关于客户端的请求信息,哪个handler正在处理它,响应结果,以及其他细节。如果你希望记录所有的请求细节(包括潜在的敏感信息),你可以打开 spring.mvc.log-request-details[]
或 spring.codec.log-request-details[]
配置。
8.3. 自动重启
使用spring-boot-devtools的应用程序会在classpath上的文件发生变化时自动重启。当在IDE中工作时,这可能是一个有用的功能,因为它为代码变化提供了一个非常快速的反馈。默认情况下,classpath上任何指向目录的条目都会被监测到变化。注意,某些资源,如静态资源和视图模板发生变化时,不需要重启应用程序。
如果你用Maven或Gradle的构建插件重启,你必须将 forking 设置为 enabled 。
如果你禁用 forking ,devtools使用的“应用隔离类加载器(isolated application classloader)”将不会被创建,重启功能将无法正常运行。
|
与LiveReload一起使用时,自动重启的效果非常好。 详见 LiveReload 部分。 如果你使用JRebel,自动重启被禁用,而采用动态类重载。 其他devtools特性(如LiveReload和属性覆盖)仍然可以使用。 |
DevTools依靠应用程序上下文的关机hook来在重启期间关闭它。
如果你禁用了关机钩子( SpringApplication.setRegisterShutdownHook(false) ),它就不能正确工作。
|
DevTools需要定制 ApplicationContext 所使用的 ResourceLoader 。
如果你的应用程序已经提供了一个,它将被“包装”(装饰者设计模式)起来。
不支持直接覆盖 ApplicationContext 上的 getResource 方法。
|
在使用AspectJ 切面时,不支持自动重启。 |
8.3.1. 记录条件评估的变化
默认情况下,每次你的应用程序重新启动时,都会记录一份显示条件评估delta的报告。 该报告显示了你的应用程序的自动配置的变化,因为你做了一些改变,如添加或删除Bean和设置配置属性。
要禁用报告的记录,请设置以下属性。
spring.devtools.restart.log-condition-evaluation-delta=false
spring:
devtools:
restart:
log-condition-evaluation-delta: false
8.3.2. 排除资源
某些资源在被改变时不一定需要触发重启。例如,Thymeleaf模板可以就地编辑。默认情况下,改变 /META-INF/maven
, /META-INF/resources
, /resources
, /static
, /public
, /templates
中的资源不会触发重启,但会触发实时重载.。如果你想自定义这些排除项,可以使用 spring.devtools.restart.exclude
属性。例如,要只排除 /static
和 /public
,你可以设置以下属性。
spring.devtools.restart.exclude=static/**,public/**
spring:
devtools:
restart:
exclude: "static/**,public/**"
如果你想保留这些默认值并增加额外的排除资源,请使用 spring.devtools.restart.extra-exclude 属性来代替。
|
8.3.4. 禁止重启
如果你不想使用重启功能,你可以通过使用 spring.devtools.restart.enabled
属性来禁用它。在大多数情况下,你可以在你的 application.properties 中设置这个属性(这样做仍然会初始化restart 类加载器,但它不会监控文件变化)。
如果你需要完全禁用重启支持(例如,因为它不能与特定的库一起工作),你需要在调用 SpringApplication.run(…)
之前将 spring.devtools.restart.enabled
属性设置为 false ,如下面的例子中所示。
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApplication.class, args);
}
}
@SpringBootApplication
object MyApplication {
@JvmStatic
fun main(args: Array<String>) {
System.setProperty("spring.devtools.restart.enabled", "false")
SpringApplication.run(MyApplication::class.java, *args)
}
}
8.3.5. 使用 trigger file
如果你只想在在特定时间触发重启,你可以使用 “trigger file”,这是一个特殊的文件,当你想实际触发重启检查时,那你就对这个文件进行修改。
对文件的任何更新都会触发检查,但只有当Devtools检测到它有改动发生时,才会实际重新启动。 |
通过属性 spring.devtools.restart.trigger-file
设置trigger file 文件的名称(不包括任何路径)。
trigger file必须在classpath路径上。
例如,如果你有一个结构如下的项目。
src +- main +- resources +- .reloadtrigger
那么你的 “trigger-file” 属性应该设置为如下。
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
现在只有当 src/main/resources/.reloadtrigger
被更新时才会重新启动。
你可能想把 spring.devtools.restart.trigger-file 设置为全局设置,这样你的所有项目都会以同样的方式行事。
|
有些IDE有一些功能,使你不需要手动更新你的触发器文件。 Spring Tools for Eclipse 和 IntelliJ IDEA (Ultimate Edition))都有这种支持。对于Spring Tools,你可以使用控制台视图中的 “reload” 按钮(需要把你的 trigger-file
命名为 .reloadtrigger
)。对于IntelliJ IDEA,你可以按照其文档中的说明进行操作。
8.3.6. 自定义重启类加载器(Restart Classloader)
正如前面在"Restart vs Reload"所描述的,重启功能是通过使用两个classloader实现的。如果这导致了其他的问题,你可能需要自定义类加载器。
默认情况下,你的IDE中任何打开的项目都是用 “restart” 类加载器加载的,而任何常规的 .jar
文件都是用 “base” 类加载器加载。
如果你使用 mvn spring-boot:run
或 gradle bootRun
也是一样:包含了 @SpringBootApplication
的项目用 “restart” 类加载器加载,其他都用 “base” 类加载器。
你可以通过创建 META-INF/spring-devtools.properties
文件来指定Spring Boot用不同的类加载器来加载你的项目的不同部分。
spring-devtools.properties
文件可以包含以 restart.exclude
和 restart.include
开头的属性。
include
元素是应该被“拉”到 “restart” 类加载器中的项目,而 exclude
元素是应该被“推”到 “base” 类加载器中的项目。
该属性的值是一个基于classpath的正则表达式,如以下例子所示。
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"
所有的key必须是唯一的。只要一个属性以 restart.include. 或 restart.exclude. 开头,就会被考虑进去。
|
所有在classpath的 META-INF/spring-devtools.properties 都会被加载。
你可以把它打包到你的项目中,或者打包进你项目依赖的项目中。
|
8.4. LiveReload
spring-boot-devtools
模块包括一个内嵌的LiveReload服务器,可以用来在资源发生变化时触发浏览器刷新。LiveReload浏览器扩展可以从 livereload.com免费获得,支持Chrome、Firefox和Safari。
如果你不想在应用程序运行时启动LiveReload服务器,你可以将 spring.devtools.livereload.enabled
属性设置为 false
。
你一次只能运行一个LiveReload服务器。 在启动你的应用程序之前,确保没有其他LiveReload服务器正在运行。 如果你从你的IDE启动多个应用程序,只有第一个有LiveReload支持。 |
为了在文件变化时触发LiveReload,必须启用 “自动重启”。 |
8.5. 全局设置
你可以通过在 $HOME/.config/spring-boot
目录下添加以下任何文件来配置全局的devtools设置。
-
spring-boot-devtools.properties
-
spring-boot-devtools.yaml
-
spring-boot-devtools.yml
添加到这些文件中的任何属性都适用于你机器上使用devtools的 所有 Spring Boot应用程序。
例如,如果要将重启配置为总是使用trigger file,你可以在 spring-boot-devtools
文件中添加以下属性。
spring.devtools.restart.trigger-file=.reloadtrigger
spring:
devtools:
restart:
trigger-file: ".reloadtrigger"
默认情况下,$HOME
是用户的主目录。
要自定义这个位置,请设置 SPRING_DEVTOOLS_HOME
环境变量或 spring.devtools.home
系统属性。
如果在 $HOME/.config/spring-boot 中找不到devtools配置文件,则会在 $HOME 目录的根部搜索是否有 .spring-boot-devtools.properties 文件。
这允许你与那些不支持 $HOME/.config/spring-boot 位置的旧版Spring Boot的应用程序共享devtools全局配置。
|
devtools properties/yaml文件中不支持Profiles。 任何在 |
8.5.1. 配置文件系统的监控
FileSystemWatcher 的工作方式是以一定的时间间隔轮询类的变化,然后等待一个预定义的安静期,以确保不再有变化。
由于Spring Boot完全依赖IDE来编译并将文件复制到Spring Boot可以读取的位置,你可能会发现有时devtools重新启动应用程序时,某些变化并没有反映出来(没有立即生效)。
如果你经常观察到这样的问题,可以尝试增加 spring.devtools.restart.poll-interval
和 spring.devtools.restart.quiet-period
参数到适合你开发环境的值。
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
spring:
devtools:
restart:
poll-interval: "2s"
quiet-period: "1s"
受监控的classpath目录现在每2秒轮询一次变化,并保持1秒的安静期以确保没有额外的类变化。
8.6. 远程应用
Spring Boot的开发者工具并不局限于本地开发。 你也可以在远程运行应用程序时使用一些功能。 远程支持是可选的,因为启用它可能会有安全风险。 只有在受信任的网络上运行时,或在用SSL保护时,才应启用它。 如果这两个选项对你来说都不可用,你就不应该使用DevTools的远程支持。 你更不应该在生产环境中启用它。
要启用它,你需要确保 devtools
包含在重新打包的归档文件(jar)中,如以下所示。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
然后你需要设置 spring.devtools.remote.secret
属性。
就像任何重要的密码或密钥一样,这个值应该是唯一的和足够强大的,以至于它不能被猜到或被暴力破解。
Remote devtools support is provided in two parts: a server-side endpoint that accepts connections and a client application that you run in your IDE.
The server component is automatically enabled when the spring.devtools.remote.secret
property is set.
The client component must be launched manually.
远程devtools支持由两部分组成:一个接受连接的服务器端端点和一个你在IDE中运行的客户端应用程序。
当 spring.devtools.remote.secret
属性被设置时,服务器组件会自动启用。
客户端组件必须手动启动。
Spring WebFlux应用程序不支持远程devtools。 |
8.6.1. 运行远程客户端程序
远程客户端应用程序被设计成可以在你的IDE中运行。
你需要运行 org.springframework.boot.devtools.RemoteSpringApplication
,其classpath与你所连接的远程项目相同。
该应用程序的唯一必要参数是它所连接的远程URL。
例如,如果你使用的是 Eclipse 或 Spring Tools,并且你有一个名为 my-app
的项目,并已将其部署到 Cloud Foundry,你可以执行以下操作。
-
从
Run
菜单中选择Run Configurations…
。 -
创建一个新的
Java Application
“launch configuration”。 -
浏览
my-app
项目。 -
使用
org.springframework.boot.devtools.RemoteSpringApplication
作为main类。 -
在
Program arguments
中添加https://myapp.cfapps.io
(或者你的远程URL)。
一个正在运行的远程客户端可能类似于如下。
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \ \\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) ) ' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / / =========|_|==============|___/===================================/_/_/_/ :: Spring Boot Remote :: (v3.2.0-SNAPSHOT) 2023-09-10T13:32:07.711+08:00 INFO 16764 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication v3.2.0-SNAPSHOT using Java 17 with PID 16764 (/Users/myuser/.m2/repository/org/springframework/boot/spring-boot-devtools/3.2.0-SNAPSHOT/spring-boot-devtools-3.2.0-SNAPSHOT.jar started by myuser in /opt/apps/) 2023-09-10T13:32:07.764+08:00 INFO 16764 --- [ main] o.s.b.devtools.RemoteSpringApplication : No active profile set, falling back to 1 default profile: "default" 2023-09-10T13:32:08.094+08:00 INFO 16764 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729 2023-09-10T13:32:08.121+08:00 INFO 16764 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 1.388 seconds (process running for 2.843)
因为远程客户端使用的是与真实应用程序相同的classpath,它可以直接读取应用程序属性。
spring.devtools.remote.secret 属性就是这样被读取并传递给服务器进行验证的。
|
始终建议使用 https:// 作为连接协议,这样流量会被加密,密码也不会被截获。
|
如果你需要使用代理来访问远程应用程序,可以配置 spring.devtools.remote.proxy.host 和 spring.devtools.remote.proxy.port 属性。
|
8.6.2. 远程更新
远程客户端以与本地 restart相同的方式监控你的应用程序classpath的变化。任何更新的资源都会被推送到远程应用程序,并(如果需要)触发重启。如果你在一个云服务上进行功能迭代,而你在本地没有云服务,这可能会很有帮助。一般来说,远程更新和重启要比完整的重建和部署周期快得多。
在一个较慢的开发环境中,可能会发生“等待时间”不够的情况,类的变化可能被分成几批。 在第一批类的变化被上传后,服务器被重新启动。 下一批则不能被发送到应用程序,因为服务器正在重启。
这通常表现为 RemoteSpringApplication
日志中的警告,即未能上传一些类,并随之重试。
但它也可能导致应用程序代码不一致,以及在第一批修改上传后无法重新启动。
如果你经常观察到这样的问题,可以尝试增加 spring.devtools.restart.poll-interval
和 spring.devtools.restart.quiet-period
参数到适合你开发环境的值。
参见"配置文件系统监听器"一节,以配置这些属性。
文件只在远程客户端运行时被监控。 如果你在启动远程客户端之前改变了一个文件,它不会被推送到远程服务器上。 |
9. 打包应用,部署到生产环境
可执行jar可以用于生产环境,由于它们是独立的,非常适合部署到云服务中。
对于额外的 “生产就绪” 功能,如健康、审计和度量REST或JMX端点,考虑添加 spring-boot-actuator
。详情见 actuator。
10. 接下来读什么
你现在应该明白如何使用Spring Boot以及应该遵循的一些最佳实践。现在你可以继续深入了解 Spring Boot 特性 ,或者你可以跳过前面,阅读Spring Boot的 “生产就绪” 方面的内容。