1. Build Systems
1.1. Dependency Management
SpringBoot每个版本都会提供一个它所支持的依赖项列表。你在使用的时候不需要给这些依赖项配置版本,SpringBoot会管理他们。当你升级SpringBoot的时候,这些依赖项也会以一致的方式升级。
你也可以指定明确的版本,覆盖SpringBoot推荐的依赖项版本。
这个依赖项列表包含所有spring启动时可以使用的spring模块,以及第三方库的细化列表。该列表作为标准清单,可以和maven和gradle一起使用。
每个SpringBoot版本都会和Spring框架的基础版本相关联。我们强烈建议,你不要明确指定依赖的版本,使用SpringBoot推荐的版本。
1.2. Maven
Maven使用者可以在spring-boot-starter-parent项目中去获得一些比较合理的默认配置。这个父依赖提供了以下特性:
- java1.8作为默认的编译器级别
- UTF-8编码格式
- 一个版本依赖管理节点,从POM文件中继承,管理所有公共依赖的版本号,它可以让我们省略依赖的版本号。
- 使用重新打包id执行重新打包目标
- 合理的资源过滤
- 合理的插件配置
注意:application.properties和application.yml文件接受Spring风格的占位符(${...}),Maven的占位符被改成了使用@....@(你可以使用maven属性resource.delimiter覆盖它)
1.2.1. Inheriting the Starter Parent
配置你的工程继承自spring-boot-starter-parent像下面这样设置parent属性:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
</parent>
你只需要在你的依赖中指定SpringBoot的版本号就ok,如果你引入额外的Starters,你可以放心的省略他们的版本号。
你可以使用properties属性重写依赖版本。例如:你想升级SpringData的发布版本,你可以这样:
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
检查SpringBoot依赖列表(POM)所有支持的属性:
https://github.com/spring-projects/spring-boot/tree/v2.2.4.RELEASE/spring-boot-project/spring-boot-dependencies/pom.xml
1.2.2. Using Spring Boot without the Parent POM
不是所有人喜欢继承spring-boot-starter-parent,你可以有自己的标准的parent,或者您可能更喜欢显式地声明所有Maven配置。
如果你不想使用spring-boot-starter-parent,你仍然可以通过使用scope=import dependency来保持依赖管理(而不是插件管理)的好处,如下所示:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
前面的例子不允许你覆盖某个依赖的版本,为了达到相同的效果,你需要在dependencyManagement增加一个条目。举个例子:你如果要覆盖SpringData的版本:
<dependencyManagement>
<dependencies>
<!-- Override Spring Data release train provided by Spring Boot -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Fowler-SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在上面的例子中我们指定一个BOM,但是所有依赖类型都可以通过这样的方式修改
1.2.3. Using the Spring Boot Maven Plugin
SpringBoot提供了一个Maven插件来打包项目生成一个可执行的JAR,在<plugins>添加Maven插件如果你想使用它的话:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
1.5. Starters
启动器是一组非常非常方便的依赖描述符,你可以获得一站式的Spring服务,比如你想用JPA,你可以使用spring-boot-starter-data-jpa依赖在你的项目当中。
所有官方的启动器使用一个命名格式:spring-boot-starter-*
第三方的启动器不要以spring-boot开头命名,第三方的启动器可以这样命名:thirdpartyproject-spring-boot-starter.
2.1. Using the “default” Package
当一个类不被包含在包里面时,它会被认为当前在默认包下(default package)。使用默认包是不推荐的,应该避免这种使用方法他可能会在使用@ComponentScan、
@ConfigurationPropertiesScan、@EntityScan、@SpringBootApplication注解的时候引起一些问题,因为每个jar包里面的每个类都是可以被访问的。
我们推荐使用Java传统的命名方式,将域名倒写:com.yu.test
2.2. Locating the Main Application Class
我们推荐把SpringBoot的MainApplication放到一个根目录下,@SpringBootApplication注释通常放在主类上,它隐式地为某些项定义了一个基本的“搜索包”。例如,如果您正在编写一个JPA应用程序,那么@SpringBootApplication注释类的包将用于搜索@Entity项。
如果你不想使用@SpringBootApplication,你可以使用@EnableAutoConfiguration 和@ComponentScan去代替它
3. Configuration Classes
虽然SpringBootApplication可以和XML文件配合使用,但是我们推荐你把配置源写成一个单独的类,使用@Configuration注解
3.1. Importing Additional Configuration Classes
您不需要将所有@Configuration放到单个类中。@Import注释可用于导入其他配置类。或者,您可以使用@ComponentScan来自动获取所有Spring组件,包括@Configuration类。
3.2. Importing XML Configuration
如果您必须使用基于XML的配置,我们建议你仍然从@Configuration类开始。然后可以使用@ImportResource注释来加载XML配置文件。
4. Auto-configuration
Spring Boot自动配置尝试根据添加的jar依赖项自动配置Spring应用程序。例如,如果HSQLDB在您的类路径中,并且您没有手动配置任何数据库连接bean,那么Spring Boot将自动配置内存中的数据库。
您需要通过将@EnableAutoConfiguration或@SpringBootApplication注释添加到您的@Configuration类之一来选择自动配置。
你应该只添加一个@SpringBootApplication或@EnableAutoConfiguration注释。我们通常建议只向主@Configuration类添加一个或另一个。
4.1. Gradually Replacing Auto-configuration
你可以定义自己的Configuration去代替自动配置的某个部分。比如,如果你添加了你自己的DataSource对象,则默认嵌入的数据库支持将后退。
如果你想知道自动配置都配置了些什么,或者为什么这样,你可以用--debug模式启动程序
这样做可以为选择的核心日志记录器启用调试日志,并将条件报告记录到控制台。
4.2. Disabling Specific Auto-configuration Classes
如果你不想让某个自动配置类被应用,那么你可以在@SpringBootApplication中使用“exclude”属性,去禁用他们:
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication {
}
如果配置类不在类路径上,你可以使用excludeName属性去指定它的全限定类路径。如果你使用@EnableAutoConfiguration,exclude和excludeName也是可以使用的。最后,你也可以使用这个spring.autoconfigure.exclude去排除
5. Spring Beans and Dependency Injection
如果按照上面的建议构造代码(将应用程序类定位在根包中),则可以添加@ComponentScan而不需要任何参数。所有应用程序组件(@Component、@Service、@Repository、@Controller等)都自动注册为Spring bean。
6. Using the @SpringBootApplication Annotation
一个单独的@SpringBootApplication 注解可以包含:
- @EnableAutoConfiguration
- @ComponentScan
- @Configuration
7.Hot Swapping
热部署可以使用JRebel,spring-boot-devtools也支持热部署
8. Developer Tools
spring-boot-devtools模块可以被包含在任意的项目以提供一些额外的开发时特性。如果要使用它,在Maven中添加如下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
在运行完全打包的程序时,将自动禁用开发人员工具。如果你的应用是从"java -jar"或者是从一个特殊的类加载器启动的时候,它会被认为是一个"production application"。如果你想禁用开发人员工具,那么请排除devtools或者设置-Dspring.devtools.restart.enabled=false系统属性。
默认情况下,重新打包的归档文件不包含devtools。如果你想使用某个远程devtools特性,您需要禁用excludeDevtools构建属性来包含它:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
8.1. Property Defaults
SpringBoot支持的一些库使用缓存来提高性能。例如:模板引擎缓存已经编译的模板,以避免重复解析模板文件。此外,在提供静态资源时,SpringMVC可以向响应添加HTTP缓存头。
当缓存在一个项目中起作用的时候,有时候他会阻止你看到你对项目的更改。所以,spring-boot-devtools默认禁用缓存选项。
缓存选项通常通过application.properties配置文件配置。例如:
Thymeleaf提供了spring.thymeleaf.cache属性。
spring-boot-devtools模块不需要手动设置这些属性,而是自动应用合理的开发时配置。
因为你在开发SpringMVC应用或者Spring WebFlux应用的时候,需要一些关于web请求的信息。所以开发者工具将为web日志组启用调试日志。它将为您提供有关传入请求、正在处理它的处理程序、响应结果等信息。如果希望记录所有请求细节(包括潜在的敏感信息),请打开spring.http.log-request-details配置属性。
如果不希望应用属性默认值,可以将application.properties中的spring.devtools.add-properties设置为false。
有关devtools应用的属性的完整列表,请参见DevToolsPropertyDefaultsPostProcessor.
8.2. Automatic Restart
可以使用spring-boot-devtools当类路径有文件改动的时候会自动重启。默认情况下,类路径中指向文件夹的任何条目都将被监视,以查看是否有更改。请注意,某些资源(如静态资源和视图模板)不需要重新启动应用程序。
由于DevTools监视类路径资源,触发重新启动的唯一方法是更新类路径。更新类路径的方式取决于所使用的IDE。在Eclipse中,保存修改后的文件将导致更新类路径并触发重启。在IntelliJ IDEA中,构建项目(Build +→+ Build项目)具有相同的效果。
当与LiveReload一起使用时,自动重启效果非常好。有关详细信息,请参阅LiveReload部分。See the LiveReload section
如果使用JRebel,则禁用自动重新启动,以便动态类重新加载。其他devtools特性(如LiveReload和属性覆盖)仍然可以使用。
DevTools依赖于应用程序上下文的shutdown hook在重启时关闭它。如果您禁用了它(SpringApplication.setRegisterShutdownHook(false)),它就不能正常工作。
当决定类路径上的一个条目更改时是否应该触发重启时,DevTools会自动忽略名为springboot,springboot-devtools,springboot-autoconfigure,springboot-actuator和springboot-starter
DevTools需要自定义ApplicationContext使用的ResourceLoader。如果您的应用程序已经提供了一个,那么它将被包装。不支持直接覆盖ApplicationContext上的getResource方法。
SpringBoot提供的重启技术工作在两个类加载器上面。不更改的类(例如,来自第三方jar的类)被加载到基类加载器中。您正在积极开发的类被加载到一个restart类加载器中。当应用程序重新启动时,将丢弃restart类加载器并创建一个新类加载器。这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基类加载器已经可用并被填充了。
如果您发现重新启动对于您的应用程序来说不够快,或者您遇到了类加载问题,那么您可以考虑重新加载技术,例如来自ZeroTurnaround的JRebel。这些工作是通过在装入类时重写它们,使它们更易于重新装入。
8.2.1. Logging changes in condition evaluation
默认情况下,每次应用程序重新启动时,都会记录一个显示条件评估增量的报告。当您进行更改(如添加或删除bean和设置配置属性)时,该报告将显示对应用程序的自动配置的更改。
如果你想禁用他,设置这个属性:
spring.devtools.restart.log-condition-evaluation-delta=false
8.2.2. Excluding Resource
某些资源在更改时不一定需要重新启动。例如,Thymeleaf模板可以就地编辑。默认情况下,更改/META-INF/maven、/META-INF/resources、/resources、/static、/public或/templates中的资源不会触发重启,但会触发动态重新加载。如果您想要自定义这些排除,您可以使用spring.devtools.restart.exclude属性。例如,要仅排除/static和/public,您需要设置以下属性:
spring.devtools.restart.exclude=static/**,public/**
8.2.3. Excluding Resource
当你更改不在类路径上的文件时,您可能希望重新启动或重新加载应用程序。为此,请使用spring.devtools.restart.additional-paths属性配置其他路径以监视更改。你可以使用前面描述的spring.devtools.restart.exclude属性来控制附加路径下的更改是触发完全重新启动还是部分重新加载。
8.2.4. Disabling Restart
如果你不希望使用热部署,你可以使用spring.devtools.restart.enabled属性禁用他。在大多数情况下,可以在应用程序中设置此属性(这样做仍然会初始化restart classloader,但它不会监视文件更改)。
如果你想完全禁用它,你可以在调用SpringApplication.run之前将spring.devtools.restart.enabled系统属性设置为false。像下面这样:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
8.2.5. Using a Trigger File
如果您使用的IDE不断地编译更改后的文件,那么您可能更希望只在特定的时间触发重新启动。为此,您可以使用一个“触发器文件”,它是一个特殊的文件,当您想要实际触发重启检查时,必须对其进行修改。
对文件的任何更新都将触发一次检查,但是只有在Devtools检测到需要执行某些操作时,才会实际重新启动。
设置spring.devtools.restart.trigger-file属性指定你的触发器文件的位置,触发器文件必须出现在类路径中的某个位置。
例如:使用下面的目录结构:
src
+- main
+- resources
+- .reloadtrigger
然后你的applictaion.properties文件的属性设置为:spring.devtools.restart.trigger-file=.reloadtrigger
现在只有在triggerFile发生更新的时候才会重新启动
8.2.6. Customizing the Restart Classloader
在前面的Restart vs Reload一节中所描述过,重新启动功能是通过使用两个类加载器实现的。对于大多数应用程序,这种方法工作得很好。然而,它有时会导致类加载问题。
默认情况下,IDE中任何打开的项目都是用“restart”类加载器加载的,而任何常规的.jar文件都是用“base”类加载器加载的。如果你处理的是一个多模块项目,而不是每个模块都导入到IDE中,那么您可能需要自定义一些东西。为此,您可以创建一个META-INF/spring-devtools属性文件。
spring-devtools.properties文件可以包含restart.exclude和restart.include的前缀。include属性包含的元素是应该被拉入“restart”类加载器的属性,exclude包含的属性是应该被拉入“base”类加载器的属性。
属性的值是一个正则表达式,如下面:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\.]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\.]+\.jar
8.2.7. Known Limitations
对于使用标准的ObjectInputStream反序列化的对象,重新启动不能很好的工作。如果你需要反序列化数据,你需要使用Spring的ConfigurableObjectInputStream和Thread.currentThread().getContextClassLoader()相结合。
8.3. LiveReload
spring-boot-devtools模块包含一个内嵌的LiveReload服务器,可以用来在资源更改时触发浏览器刷新。LiveReload浏览器扩展可免费用于Chrome、Firefox和Safari livereload.com.
如果你不想让LiveReload服务运行,那么你可以设置spring.devtools.livereload.enabled属性为false
一次只能运行一个LiveReload服务器。在启动应用程序之前,请确保没有其他的LiveReload服务器在运行。如果您从IDE启动多个应用程序,那么只有第一个具有LiveReload支持。
8.4. Global Settings
你可以向$HOME/.config/spring-boot目录添加以下文件来配置全局devtools设置:
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
添加到这些文件中的任何属性都适用于您机器上使用devtools的所有的Spring启动应用程序。例如,要将restart配置为始终使用触发器文件,您需要添加以下属性:
// 文件路径
~/.config/spring-boot/spring-boot-devtools.properties
// 添加的属性
spring.devtools.restart.trigger-file=.reloadtrigger
如果在$HOME/.config/spring-boot中没有找到devtools配置文件。将会在根目录($HOME)下搜索是否存在spring-boot-devtools.properties文件。这允许您与不支持$HOME/.config/spring-boot/的旧版Spring Boot的应用程序共享devtools全局配置.
8.5. Remote Applications
开发人员工具并不局限于本地开发使用,在远程运行应用程序时,也可以使用。但是它存在一定的安全风险, 只有在受信任的网络上运行或者使用SSL进行保护时,才应该启用它。如果这两个选项都不可用,就不应该使用DevTools的远程支持。永远不要在生产部署上启用支持。
要启用它,您需要确保重新打包的归档文件中包含devtools,如下面的清单所示:
<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属性。与任何重要的密码或秘密一样,该值应该是唯一的、强的,这样就不会被猜测或强行使用。
远程devtools支持由两部分提供:接受连接的服务器端端点和在IDE中运行的客户机应用程序。当设置spring.devtools.remote.secret属性时,服务器组件将自动启用。客户端组件必须手动启动。
8.5.1. Running the Remote Client Application
远程客户端应用程序被设计在IDE中运行。您需要使用与您连接的远程项目相同的类路径来运行org.springframework.boot.devtools.RemoteSpringApplication。应用程序唯一需要的参数是它所连接的远程URL。
例如,如果你正在使用IDEA,并且你有一个名为my-app的项目,你已经部署到云服务器,你会做以下事情:
1.在Run菜单中选择"Edit Configurations"
2.创建一个新的启动配置,选择SpringBoot,并且选择你的Remote主程序,你如你的Remote主程序的名字是”org.springframework.boot.devtools.RemoteSpringApplication“
- 把你的远程URL填到 "program arguments"属性列里面
注意:通常建议使用https://作为连接协议,这样就可以对流量进行加密,并且不会截获密码。
如果需要使用代理访问远程应用程序,请配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性。
8.5.3. Configuring File System Watcher
FileSystemWatcher的工作方式是,在一定的时间间隔内轮询类更改,然后等待预定义的静默期,以确保不再发生更改。然后将更改上传到远程应用程序。在较慢的开发环境中,可能会发生这样的情况:安静期不够长,类中的更改可能被分割为多个批。上传第一批类更改后,服务器将重新启动。下一批数据不能发送到应用程序,因为服务器正在重新启动。
可能会发生一些RemoteSpringApplication日志中关于上传一些类失败的警告,以及随后的重试。但是,它也可能导致应用程序代码不一致,并且在上传第一批更改后无法重新启动。
如果你经常观察到这种现象,请尝试将spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period参数增加到适合您的开发环境的值:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
这样的配置的意识是被监视的classpath文件夹现在每2秒轮询一次,以查找更改,并保持1秒的静默期,以确保没有其他类更改。