1 构建系统
强烈推荐你选择一款支持依赖管理的构建系统,这样的构建系统可以让你通过artifacts连接Maven中心仓库。Maven或者Gradle就是不错的选择。也可以使用其他的构建系统来使用Sping Boot,例如Ant,但是对他们的支持没那么好。
1.1 依赖管理
Spring Boot的每个版本都会提供它支持的依赖清单。你不需要为这些依赖提供版本号,因为Spring Boot帮你管理了。当你更新Spring Boot时,这些依赖也会自动更新。
如果你需要,你也可以指定版本号来覆盖spring boot的默认值。
这份清单列出了所有可以和Spring Boot配合使用的Spring模块和一份精简的第三方库列表。这份清单是一个可以用于Maven和Gradle的标准的 Bills of Materials
。
每个Spring Boot都内联了一个Spring的基础版本,强烈建议不要修改这个版本号。
1.2 Maven
Maven用户可以从spring-boot-starter-parent项目继承默认项,这个父工程提供以下功能:
- 默认Java 1.8为编译器
- 源码编码为UTF-8
- 从spring-boot-dependencies继承而来的pom文件管理着通用依赖版本。依赖管理可以让你不用理会你使用的依赖的<version>
-
repackage
goal对应着一个执行id - Sensible resource filtering
- Sensible plugin configuration (exec plugin, Git commit ID, and shade)
- Sensible resource filtering for application.properties and application.yml including profile-specific files (for example, application-dev.properties and application-dev.yml)
1.2.1 继承父starter
配置项目继承spring-boot-starter-parent,设置如下:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
你只需要指定Spring Boot的版本号。除此之外的starters,不指定版本号也没问题。
在你的项目中使用如上设置后,可以通过属性覆盖来实现依赖覆盖。例如,升级Spring Data release train可以使用如下设置:
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
点击 spring-boot-dependencies
pom
查看支持的属性。
1.2.2 不使用PARENT POM
有些用户可能不喜欢继承spring-boot-starter-parent的方式。 你自己有一个标准的parent或者你想明确声明所有的Maven配置。
如果你不想使用spring-boot-starter-parent,你也仍然可以享受依赖管理的便利(不是插件管理),这需要一个scope=import依赖,如下:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这样的设置不能实现通过property进行依赖覆盖。为了实现同样的效果,可以在dependencyManagement 的
spring-boot-dependencies之前加一条设置。例如,同样升级Spring Data release train的版本,你可以这样做:
<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.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在上面的例子中,我们定义了一个BOM(Bill of Material,即物料清单)文件,但是任何依赖类型都可以用同样的方式来覆盖。
1.2.3 Spring Boot Maven插件的使用
Spring Boot中含有 Maven plugin
,它可以把项目打包成可执行的jar文件。你可以像这样来添加插件:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
如果你用了Spring Boot starter parent,把插件加上就可以了,不需要配置,除非你想修改parent中的默认设置。
1.3 Gradle
如果想了解怎么用Gradle使用Spring Boot,可以参考Spring Boot的Gradle插件文档:
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="2.2.1.RELEASE" />
<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,点击这里 howto.html
1.5 启动器Starter
启动器是你可以在应用(application)中使用的一系列便利的依赖描述器。可以把你从复制-粘贴依赖描述的负担中解脱出来。如果你想用Spring和JPA操作数据库,引入spring-boot-starter-data-jpa就行了。
用启动类中包含的一系列依赖,你可以快速构建和启动一个项目, with a consistent, supported set of managed transitive dependencies.
What’s in a name
所有的官方启动器都有相似的名称,spring-boot-starter-,是一个应用类型。这种结构的命名是为了方便查找需要的启动器。许多IDEs整合了Maven,可以通过名称搜索依赖。在Eclipse或者STS中装了插件,在POM中按ctrl-space并输入“spring-boot-starter”就可以得出一个完整的列表。
在Creating Your Own Starter小节中,第三方启动器不要以spring-boot作为前缀,这是Spring Boot官方保留的关键字。第三方启动器最好以项目名称作为前缀。例如,项目名称是thirdpartyproject,那么启动器就命名为thirdpartyproject-spring-boot-starter。
要查看Spring Boot提供的启动器列表,请点击一下链接:https://www.cnblogs.com/mihasha/p/11840537.html
2 代码构建
Spring Boot不要求任何代码的层次,但有一些最佳实践可以参考。
2.1 使用默认Pachage
如果一个类没有package声明,就认为它在“default package”下。但是我们应该避免使用“default package”,因为在Spring Boot中当使用@ComponentScan, @ConfigurationPropertiesScan, @EntityScan, 或者 @SpringBootApplication注解时,这个默认包会造成特殊的问题,因为每个jar包下的类都会被读取。
我们推荐使用符合Java约定的包命名方式,并且使用反转的域名(例如,com.example.project)
2.2 主类位置
我们推荐把主类放在根目录下,在所有其他类的上级目录。@SpringBootApplication经常放在主类上,它会定义一个基础的“search package”。例如,如果你正在写一个JPA应用,@SpringBootApplication注解类的包是用来查找@Entity修饰的类的。使用根package也可以让组件只扫描你的应用。
如果你不想使用@SpringBootApplication,
@EnableAutoConfiguration和@ComponentScan注解也提供相同的功能,所以可以使用这两个注解代替。
下面是一个标准层次:
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
Application.java文件会声明main方法,使用@SpringBootApplication,如例:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3 配置类
3.1 导入额外的配置类
我们不必使用@Configuration在一个类上完成所有的配置,可以使用@Import导入其他的配置类,或者可以使用@ComponentScan来自动扫描所有的Spring组件引入配置类。
3.2 引入XML配置
如果你不得不使用基于XML的配置,我们推荐使用@Configuration配置类+@ImportResource注解的方式来加载XML配置文件
4 自动配置
Spring Boot会根据我们添加的jar依赖来进行自动配置,例如:如果在我们的classpath中有HSQLDB,你不必手动配置任何数据库连接beans,它会在内存中进行自动配置。
你可以在@Configuration配置类上使用@AutoConfiguration或者@SpringBootApplication注解来开启自动配置。
TIPS:每个应用只应该使用@AutoConfiguration或者@SpringBootApplication其中之一,推荐将其中一个注解添加在主@Configuration配置类上。
4.1 逐步取代自动配置
自动配置是非侵入式的(non-invasive),任何时候你都可以定义自己的配置来替代其中的一部分。假如你定义了一个DataSource Bean,嵌入的默认数据库支持会回收。
如果你想了解自动配置项和原因,你可以使用--Dubug选项启动应用(mvn spring-boot:run --debug),这些信息会打印到控制台上。
4.2 移除指定的配置类
如果你不想使用某个自动配置类,可以使用@EnableAutoConfiguration注解的exclude属性来设置,如下所示:
> import org.springframework.boot.autoconfigure.*;
> import org.springframework.boot.autoconfigure.jdbc.*;
> import org.springframework.context.annotation.*;
> @Configuration(proxyBeanMethods = false)
> @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
> public classMyConfiguration{}
如果你的类不在classpath下,你可以使用这个注解的excludeName属性,值为类的全包名来进行排除。你也可以使用spring.autoconfigure.exclude这个属性来控制自动配置类的列表。
TIPS:
1.注解方式和属性排除方式可以共同使用
2.虽然自动配置类的修饰符是public,但是我们可以用来取消自动配置的作为公共API的部分仅仅是这个类的名字,类中的嵌套配置类、方法等等都是用于内部使用的,我们不推荐直接使用这些信息。
5 Spring实体和依赖注入
我们可以自由的定义实体和注入的依赖,@ComponentScan和@Autowired注解组合使用非常方便。
如果按照Spring Boot推荐的方式在构建代码(把主类放到根目录下),使用@ComponentScan这个注解就不需要任何参数。所有的应用组件(@Component、@Service、@Repository、@Controller等等)都会自动注册为Spring Beans。
下面的例子用来演示一个使用构造器注入的@Service实体,获得一个需要的RiskAssessor 实体。
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
如果这个实体只有一个构造器,可以忽略@Autowired注解,像下面这样:
If a bean has one constructor, you can omit the @Autowired, as shown in the following example:
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
image.png
6 @SpringBootApplication注解的使用
Spring Boot应用的开发者都希望他们的应用可以进行自动配置、组件扫描并且能够进行额外的配置。@SpringBootApplication注解可以开启以下功能:
- @EnableConfiguration:开启Spring Boot自动配置机制
- @ComponentScan:开启扫描包下@Component组件的功能
- @ConfigurationPropertiesScan:开启包下的@ConfigurationProperties扫描
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan @ConfigurationPropertiesScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
TIPS
1.@SpringBootApplication也支持别名去自定义@EnableAutoConfiguration和@ComponentScan的属性;
2.可以使用开启某个功能的注解去代替@SpringBootApplication,如果在应用中想要开启组件和属性配置扫描,你可以这样写:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
7 运行你的应用
使用内嵌的HTTP服务器并把应用达成jar包的最大的优点就是你可以方便的运行你的应用。Debug一个Spring Boot应用也很容易,不需要额外的IDE插件。
TIP
这部分只包括基于jar的打包方式,如果你想把应用打包成war文件,可以参考服务器或者你的IDE文档。
-
7.1用IDE运行
在IDE中运行Spring Boot应用就像运行简单的Java程序一样,你要做的首先是导入你的应用。导入操作在不同的IDE和Build System中可能不同,大多数的IDE都能直接导入Maven项目。例如,Eclipse用户可以在File菜单中选择Import… → Existing Maven Projects来导入。
如果你不能直接把工程导入到IDE,你可以使用Build System生成一个IDE的metadata(不知道咋翻译..)。Maven有Eclipse和IDEA的插件,Gradle为多种IDE提供插件。
TIPS
如果你不小心运行了2次web应用,你会看到“Port already in user”(端口被占用)错误,STS用户可以使用Relauch按钮而不是Run按钮来保证生成的实例先被关闭。 -
7.2运行一个打包好的应用
如果你使用Maven或者Gradle插件生成的jar文件,你可以使用java -jar命令,如下所示:
java -jar target/myapplication-0.0.1-SNAPSHOT.jar
也可以运行一个支持远程调试的打包好的应用,这会绑定一个调试器到你打包好的应用中,命令如下所示:
It is also possible to run a packaged application with remote debugging support enabled. Doing so lets you attach a debugger to your packaged application, as shown in the following example:
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命令可以快速编译和启动应用。应用是独立运行的。下面是经典的运行Spring Boot应用的Maven命令:
mvn spring-boot:run
你可以使用MAVEN_OPTS操作系统环境变量:
export MAVEN_OPTS=-Xmx1024m
-
7.4使用Gradle插件
这个插件有一个bootRun任务可以独立运行Spring Boot应用。
只要你使用了org.springframework.boot和java插件,这个任务就会出现:
gradle bootRun
你可以使用JAVA_OPTS编辑环境变量:
export JAVA_OPTS=-Xmx1024m
-
7.5热更新
既然Spring Boot项目就是一个普通的Java应用,那么Jvm的热更新应该是开箱即用的。但它却有点被字节码限制了,JReble为我们提供了完整的解决方案。
spring-boot-devtools提供了一些快速重新启动应用的支持,下面马上会提到这个工具,如果想了解更多细节,点击这个链接-Hot swapping “How-to”
8 开发者工具
Spring Boot为了优化开发体验,提供了一系列工具。spring-boot-devtools可以应用在任何项目中并提供一些开发时特性。添加依赖可以引入开发者工具的支持,如下所示:
Maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
TIPS
以完整的包应用运行时,这个工具会失效。如果应用以java -jar或者用特定的类加载器启动,就会认为是生产时应用(production-application)。如果出现了特殊情况,你可以使用如下属性手动排除Dspring.devtools.restart.enabled=false
在你的应用被其他应用使用时,阻止这个工具的传递,因此把这个依赖标记为可选项,这是一种最佳实践。
重新打包的文件不会包含这个工具,如果你想使用这个工具的某个功能,你需要在编译属性设置中关闭excludeDevtools,Maven和Gradle插件都支持这个属性。
8.1 默认属性
Spring Boot的几个库都使用缓存来提高性能。例如,模板引擎为了避免反复解析模板文件将编译好的模板缓存起来,又如Spring MVC在提供静态资源服务时,可以在响应中增加HTTP缓存的headers。
缓存在生产环境中是非常有益的。但在开发环境中却适得其反,因为缓存让我们无法观察到应用刚刚做的修改。因此,spring-boot-devtools默认关闭了缓存。
缓存一般在application.properties文件中进行配置,例如,Thymeleaf提供spring.thymeleaf.cache属性。spring-boot-devtools在开发时会自动进行合理配置,不需要手动进行控制。
在开发Spring MVC和Spring WebFlux应用时,我们想看到更多的网络请求信息,此工具会开启DEBUG日志。这样我们可以看到更多的请求信息,谁在处理请求,响应信息等等。如果你想看到全部的日志信息(包括潜在的敏感信息),可以打开spring.http.log-request-details属性。
TIPS
如果你不想使用这些默认属性,可以在application.properties文件中设置spring.devtools.add-properties属性的值为false。
点击DevToolsPropertyDefaultsPostProcessor
查看开发者工具使用的所有属性。
8.2 自动重启
使用了spring-boot-devtools的Spring Boot应用中,classpath中的类文件无论何时发生变化,应用都会自动重新启动。我们在IDE中进行开发时,这个特点非常有用,因为对于代码的变化我们可以快速得到反馈。默认情况下,classpath同一文件夹下的所有目录的变化都会被检测到。视图模板和静态资源这一类的资源的变化,不需要重新启动应用。
image.pngRestart的触发
因为DevTools检测的是classpath目录下的资源的变化,触发restart的唯一方式就是更新classpath。当然,更新的方式取决于你使用的IDE。在Eclipse中,保存一个修改过的文件就会更新classpath,触发restart。在IntelliJ IDEA中,编译项目有一样的效果(Build +→+ Build Project)。
delvTools需要自定义ApplicationContext使用的ResourceLoader,如果你已经有一个ResourceLoader了,那么要去覆盖他,但是不能直接使用ApplicationContext的getResource方法来覆盖。
Restart VS Reload
Spring Boot提供的restart技术是使用两个classLoader来实现的。哪些没有任何变化的类(比如第三方jar包)被加载进base loader,哪些你正在开发的类被加载进restart loader。所以当应用重新启动的时候,这个restart loader会销毁并重新创建一个。这种实现方式意味着restart要比“cold start”速度快的多,因为base loader已经处在待命状态了。
如果你觉得restart对于你的应用来说不够快,或者你的加载器出问题了,那么你可以考虑使用ZeroTurnaround的JRebel这样的reloading技术。它的原理是在加载类的时候对其进行重写,以易于reloading。
8.2.1 Logging changes in condition evaluation(不会翻译)
默认情况下,每次应用重新启动的时候,都会有一个condition evaluation delta报告记录。如果你增加、删除一个Bean或者设置了一些配置属性,这个报告会让你看到这些修改。关闭日志,可以设置如下属性:
spring.devtools.restart.log-condition-evaluation-delta=false
8.2.2 Excluding Resources(排除资源)
某些资源的变化是不需要进行重启的。例如,Thymeleaf模板可以原地编辑。默认情况下,在以下目录中的文件不回触发重启,但是会实时重载:
/META-INF/maven, /META-INF/resources, /resources, /static, /public, or /templates
如果你想自定义排除项,可以设置spring.devtools.restart.exclude属性,例如排除/static和/public下的资源,你可以这样设置:
image.png
如果你想保留默认排除项,在此基础上增加额外的排除项,可以使用spring.devtools.restart.additional-exclude属性
8.2.3 Watching Additional Paths(监测其他路径)
应用中,如果需要实现classpath目录以外的文件的变化也能触发restart或者reload,可以设置spring.devtools.restart.additional-paths属性。如果在这个目录下的某些文件不需要restart或者reload,可以在监测前定义spring.devtools.restart.exclude属性。
8.2.4 Disabling Restart (关闭重启)
你可以使用spring.devtools.restart.enabled属性关闭重启功能。大多数情况下,你可以在application.properties设置这个属性。这样设置仍然会初始化restart classloader,但是不会再监测目录下资源的变化。
如果你要彻底关闭restart功能,你要在调用SpringApplication.run(..)之前设置spring.devtools.restart.enabled系统属性,例子如下:
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,那么你可能更希望在指定的时间来重启应用,定义一个“trigger file”,只有这个文件的修改才会触发restart的检查。
触发文件的名称(不包含任何路径)作为spring.devtools.restart.trigger-file属性的值,这个文件必须在classpath下。如果是下面这样的目录结构: image.png这个文件的任何更新都会触发检查,但是只有DevTools检查到区别应用才会真正重启
属性可以这样设置:
spring.devtools.restart.trigger-file=.reloadtrigger
只有当src/main/resources/.reloadtrigger更新的时候,应用才会restart。
你可能想全局设置spring.devtools.restart.trigger-file属性,这样你的所有项目都可以有触发文件的效果。
有些IDE可以让你不用手动更新触发文件.Spring Tools for Eclipse and IntelliJ IDEA (Ultimate Edition)
都支持这个功能。用了Spring Tools,你可以在控制台点击‘reload’按钮(只要你的trigger-file的名字是.reloadtrigger)。IntelliJ IDEA中,参考这个链接 instructions in their documentation。
。
8.2.6 Customizing the Restart Classloader(自定义重启类加载器)
就像在Restart VS Reload中说的那样,restart功能是用两个类加载器实现的。对于大多数的应用来说,这个方法很好,但是有时,可能会出现一些类加载器方面的问题。
默认情况下,在IDE中打开的项目使用的是restart classloader,.jar文件使用的是base classloader。如果你现在开发的是一个多module的项目,并且这些module没有全部导入IDE,你就可能需要自定义点啥了。怎么自定义呢,创建一个META-INF/spring-devtools.properties文件。
spring-devtools.properties文件可以有很多以restart.exclude和restart.include为前缀的属性。include的元素会被restart classloader加载,exclude的元素会被base classloader加载。属性值是一个表示classpath下目录的正则表达式,如下所示:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\.]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\.]+\.jar
image.png前缀固定,每个属性的key必须是唯一的。只要有规定的前缀,属性就能被读取。
8.2.7 Known Limitations(局限性)
当有对象被标准的ObjectInputStream反序列化时,restart功能就不太灵了。如果你要反序列化数据,你需要把Spring的ConfigurableObjectInputStream 和Thread.currentThread().getContextClassLoader()结合来使用.
不幸的是,有些第三方反序列化库没有考虑到context classloader,如果你发现这个问题,可以请求作者修复。
8.3 LiveReload(实时重载?)
spring-boot-devtools内嵌了一个实时重载服务器,当资源有变化是可以进行浏览器的刷新。Chrome、Firefox、Safari可以从livereload.com
免费下载插件。如果你不想使用重载服务器,可以设置spring.devtools.livereload.enabled为false。
同一时间只能使用一个LiveReload服务器。应用启动前,确保没有其他的LiveReload服务器在运行。如果你启动了多个应用,只有第一个应用支持LiveReload。
8.4 全局设置
可以在$HOME/.config/spring-boot下增加以下文件进行全局设置:
1、spring-boot-devtools.properties
2、spring-boot-devtools.yaml
3、spring-boot-devtools.yml
以上文件中的所有属性,都会应用到使用了DevTools的所有的Spring Boot应用。例如,配置使用触发文件来进行restart,设置如下:
~/config/spring-boot/spring-boot-devtools.properties
spring.devtools.restart.trigger-file=.reloadtrigger
image.png如果在HOME的root下找.spring-boot-devtools.properties文件。这让你可以跟那些不支持$HOME/.config/spring-boot的旧版本的Spring Boot应用共享配置。
8.5 远程应用
Spring Boot developer tools不仅仅局限于本地开发,远程运行应用时也有几个功能可用。开启远程支持有一定的风险,所以你要有一个可信任的网络环境或者一个可靠的SSL。如果两者都不满足,就不要开启DevTools的远程支持。在生产环境上,也不要开启devTools的远程支持。
要开启远程支持,重新打包的文件中必须含有devTools,这需要如下设置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
pom文件之后还要设置spring.devtools.remote.secret属性,这个属性的值要像你所有的重要的密码一样有一定的安全性,它不容易猜到也不会被暴力破解。
远程devtools支持包括以下两部分:接受连接的服务器端和运行在你IDE中的应用。spring.devtools.remote.secret属性设置后服务端会自动开启远程支持,客户端的需要手动开启。
8.5.1 运行远程客户端应用
远程客户端应用是在自己的IDE中运行的,运行classpath下的org.springframework.boot.devtools.RemoteSpringApplication,你连接的远程项目要和你的客户端项目有相同的classpath。应用的唯一参数就是你要连接的远程地址。
例如,如果你的Eclipse或者STS中有一个已经在云端部署的名为my-app的项目,你需要做以下几项工作:
- 在Run菜单中选择Run Configurations...
- 新建一个Java Application ,命名 “launch configuration”
- 选择my-app项目
- 用org.springframework.boot.devtools.RemoteSpringApplication作主类
- 把https://myapp.cfapps.io加在Program arguments上(参数是你的远程地址)
如果成功运行,控制台会有类似下面这样的输出:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.2.1.RELEASE
2015-06-10 18:25:06.632 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
2015-06-10 18:25:06.671 INFO 14938 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
2015-06-10 18:25:07.043 WARN 14938 --- [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
2015-06-10 18:25:07.074 INFO 14938 --- [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2015-06-10 18:25:07.130 INFO 14938 --- [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
因为远程客户端和真实应用使用的是相同的classpath,所以能够直接读取应用的属性。也因此才能读取到spring.devtools.remote.secret属性,并提供给服务端用于认证。
建议使用https协议,因为它的传输加密和密码不能被截取
如果要使用代理连接远程应用,配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性
8.5.2 远程更新
远程客户端监听着classpath下的资源的变化,推送到远程应用的任何更新都会触发重启。如果你在迭代一个使用云服务的功能,这点非常有用。一般情况下,远程更新和重启比rebuild和部署周期更快。
远程客户端只有在运行状态下才会监听文件的变化,如果你在启动远程客户端之前修改了一个文件,它不会推送到远程服务器。
8.5.3配置文件系统监听器
FileSystemWatcher
的工作原理是循环轮询类的变化,然后等待一段预定义的静默期以确保没有其他的修改发生。随后这些修改会上传的远程应用。如果开发环境很慢,可能导致静默期不够长。这就导致一个修改被分成了几批传到了远程应用。第一批的修改上传成功后服务就重启了,下一批就不能发送到应用中,因为服务器正在重启。
这种情况在RemoteSpringApplication 的日志中会有明显的warning日志说明:某些类上传失败,随后会重试。也可能会导致代码冲突,第一批修改上传之后应用无法重启。
如果你发现了类似的问题,可以设置2个属性来适应自己的开发环境:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
设置参数后,现在监听的classpath文件夹2s轮询一次变化,有1s的静默期确保没有额外的修改。
9 应用打包
可执行的jars可用于生产部署,因为他们是自包含的(self-contained),也非常适合基于云的开发。
更多的生产就绪特性,例如:health,auditing,metric REST or JMX终端,引入spring-boot-actuator。
production-ready-features.html
10 进阶阅读
现在你已经知道spring boot的使用和它的一些最佳实践。下面你可以继续深度学习 Spring Boot features
,或者你想跳过这部分内容直接阅读production ready
方面的知识。
网友评论