精彩文章免费看

Spring Boot 参考指南3(1.5.2.RELEASE)

此篇翻译的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spring Boot)。查看前面章节移步 这里

第三部分 使用Spring Boot

本节将更详细介绍你应该如何使用Spring Boot。 它涵盖诸如构建系统,自动配置以及如何运行应用程序等主题。 我们也涵盖了一些Spring Boot的最佳实践。虽然Spring Boot没有什么尤其特别的特点(它只是另一个你可以利用的库),这有一些建议当你按照它做时,可以让您的开发过程更容易一些。

如果您刚刚开始使用Spring Boot,那么在深入本节之前,您应该大概阅读 入门 指南。

13. 构建系统

强烈建议您选择一个支持 依赖管理 的构建系统,和一个可以消耗工件发布到“Maven Central”仓库。 我们建议您选择Maven或Gradle。 可以让Spring Boot与其他构建系统(例如Ant)配合使用,但是它们不会得到很好的支持。

13.1 依赖管理

每个版本的Spring Boot提供了一个它所支持的依赖列表。 实际上,您不需要为构建配置中的任何这些依赖提供版本,因为Spring Boot正在为您进行管理。 当您升级Spring Boot本身时,这些依赖也将以一致的方式进行升级。

Maven用户可以从 spring-boot-starter-parent-parent 项目中继承,以获得合理的默认值。父项目提供以下功能:

  • Java 1.6作为默认编译器级别。
  • 源代码是UTF-8编码。
  • 依赖管理节点(Dependency Management section) ,允许您忽略常用依赖的 version 标签,继承自 spring-boot-dependencies POM。
  • 合理的 资源过滤
  • 合理的插件配置( exec plugin , surefire , Git commit ID , shade )。
  • 合理的 application.properties application.yml 资源过滤,包括特定的profile文件(例如: application-foo.properties application-foo.yml
  • 最后一点:由于默认的配置文件接受Spring样式占位符( $ {...} ),所以Maven过滤被更改为使用 @..@ 占位符(您可以使用Maven的 resource.delimiter 属性覆盖它)。

    13.2.1 继承 starter parent

    配置你的项目从 spring-boot-starter-parent 继承,只需的设置 parent (节点):

    <!--从Spring Boot 继承默认值 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
    </parent>
    

    通过该设置,您也可以在项目中通过属性的优势覆盖个别的依赖项,例如,要升级到另一个Spring Data release train,你需要添加以下内容到你的 pom.xml :

    <properties>
        <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
    </properties>
    
    13.2.2 使用没有父POM的Spring Boot

    不是所有人都喜欢从 spring-boot-starter-parent 继承,您可能需要使用你自己团队拥有的标准 parent,或者你可能只是希望明确声明你的Maven配置。

    如果您不想使用 spring-boot-starter-parent,则仍然可以通过使用 scope=import 依赖来保持依赖管理(但不是插件管理)的好处:

    <dependencyManagement>
         <dependencies>
            <dependency>
                <!-- 从Spring Boot引入依赖管理 -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    该设置不允许您使用如上所述的属性来覆盖单个依赖。要实现相同的结果,您需要在在项目的 dependencyManagement 中,spring-boot-dependencies 条目之前添加一个条目。例如:要升级到另一个Spring Data release train,您需要将以下内容添加到您的pom.xml中。

    <dependencyManagement>
        <dependencies>
            <!-- 覆盖由Spring Boot提供的Spring Data release train -->
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-releasetrain</artifactId>
                <version>Fowler-SR2</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
    13.2.3 改变Java版本

    spring-boot-starter-parent 选择相当保守的Java兼容性。 如果要遵循我们的建议并使用更高版本的Java版本,可以添加 java.version 属性:

    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    13.2.4 使用Spring Boot Maven 插件

    Spring Boot 包含一个可以将项目打包成可执行的jar的Maven插件。如果你想用它将插件放在你的 <plugins> 节点中:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    

    13.3 Gradle

    Gradle 用户可以直接在他们的 dependencies 部分引入"starters"。不像Maven,这没有 "super parent" 去引入共享一些配置。

    repositories {
        jcenter()
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE")
    

    spring-boot-gradle-plugin 也是可用的,它提供了从源代码创建可执行jar并运行项目的任务。 它还提供依赖管理,除其他功能外,还允许您省略由Spring Boot管理的任何依赖的版本号:

    plugins {
        id 'org.springframework.boot' version '1.5.2.RELEASE'
        id 'java'
    repositories {
        jcenter()
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
        testCompile("org.springframework.boot:spring-boot-starter-test")
    

    13.4 Ant

    有可能需要使用Apache Ant+Ivy创建Spring Boot项目。spring-boot-antlib “AntLib”模块也可用于帮助Ant创建可执行jars

    要声明依赖,一个典型的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="1.3.0.BUILD-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 模块。请参见 第84.10节, “不使用spring-boot-antlib从Ant创建一个可执行的存档” ”怎么做“

    13.5 启动器

    启动器是一组可以包含在应用程序中的,方便的依赖关系描述符。 您可以获得所需的所有Spring和相关技术的一站式服务,无需通过搜寻示例代码和复制粘贴依赖描述符的加载。 例如,如果要开始使用Spring和JPA进行数据库访问,那么只需在项目中包含 spring-boot-starter-data-jpa 依赖,即可准备好去做。

    启动器包含许多您需要使项目启动并快速运行的依赖,并具有托管传递依赖一致的、受支持的集合。

    名字的含义

    所有官方的启动器都遵循类似的命名方式; spring-boot-starter-* ,其中 * 是一个特定类型的应用。这个命名结构旨在帮助你找到一个启动器。这个命名结构旨在帮助你找到一个启动器。 许多IDE中的Maven集成允许您按名称搜索依赖项。 例如,安装适当的Eclipse或STS插件后,您可以简单地在POM编辑器中点击 ctrl-space ,并输入“spring-boot-starter”来获取完整的列表。

    创建自己的启动器 部分所述,第三方启动程序不应该以 Spring-boot 开头,因为它是为正式的Spring Boot工件保留的。 acme 的第三方启动器通常被命名为 acme-spring-boot-starter

    Spring Boot在 org.springframework.boot 组下提供了以下应用程序启动器:

    表 13.1 Spring Boot 应用启动器

    |名称|描述|Pom|
    |---|---|
    | spring-boot-starter-thymeleaf |使用Thymeleaf 视图构建MVC web应用的启动器| Pom |
    | spring-boot-starter-data-couchbase |使用Couchbase面向文档的数据库和Spring Data Couchbase| Pom |
    | spring-boot-starter-artemis |使用Apache Artemis实现JMS消息| Pom |
    | spring-boot-starter-web-services |用于Spring Web服务的启动器| Pom |
    | spring-boot-starter-mail |用于Java邮件和Spring 框架的邮件发送支持的启动器| Pom |
    | spring-boot-starter-data-redis |用于Redis 的key-value数据存储同Spring Data Redis和Jedis 客户端的启动器| Pom |
    | spring-boot-starter-web |为构建使用Spring MVC包括RESTful、web的应用的启动器,使用Tomcat作为默认的内嵌容器| Pom |
    | spring-boot-starter-data-gemfire |用于GemFire分布式数据存储和Spring Data GemFire的启动器| Pom |
    | spring-boot-starter-activemq |使用Apache ActiveMQ实现JMS消息| Pom |
    | spring-boot-starter-data-elasticsearch |用于Elasticsearch搜索和分析引擎以及Spring Data Elasticsearch| Pom |
    | spring-boot-starter-integration |用于Spring集成| Pom |
    | spring-boot-starter-test |用于测试Spring Boot应用包含的库:JUnit、Hamcrest 、Mockito| Pom |
    | spring-boot-starter-jdbc |用于JDBC支持,使用Tomcat JDBC 连接池| Pom |
    | spring-boot-starter-mobile |使用Spring Mobile构建web应用的启动器| Pom |
    | spring-boot-starter-validation |用于使用Hibernate Validator的Java Bean验证启动器| Pom |
    | spring-boot-starter-hateoas |使用Spring MVC和Spring HATEOAS构建基于超媒体的RESTful web应用的启动器| Pom |
    | spring-boot-starter-jersey |使用 JAX-RS 和 Jersey构建RESTful web应用, spring-boot-starter-web 的替代方法| Pom |
    | spring-boot-starter-data-neo4j |用于Neo4j 图形数据库和Spring Data Neo4j 的启动器| Pom |
    | spring-boot-starter-data-ldap |用于Spring Data LDAP的启动器| Pom |
    | spring-boot-starter-websocket |用于构建WebSocket 应用(使用spring 框架的WebSocket 支持)的启动器| Pom |
    | spring-boot-starter-aop |用于基于Spring Aop和AspectJ的面向切面(aspect-oriented)编程的启动器| Pom |
    | spring-boot-starter-amqp |使用Spring AMQP和Rabbit MQ| Pom |
    | spring-boot-starter-data-cassandra |使用Spring Cassandra 分布式数据库和Spring Data Cassandra| Pom |
    | spring-boot-starter-social-facebook |使用Spring 社交的 facebook| Pom |
    | spring-boot-starter-jta-atomikos |用于基于Atomikos实现的JTA事务| Pom |
    | spring-boot-starter-security |用于Spring Security的启动器| Pom |
    | spring-boot-starter-mustache |用于构建Mustache 视图实现的MVC web应用| Pom |
    | spring-boot-starter-data-jpa |用于Hibernate实现的Spring Data JPA的启动器| Pom |
    | spring-boot-starter |核心启动器,包括自动配置支持、日志以及YAML| Pom |
    | spring-boot-starter-groovy-templates |使用Groovy 模版视图实现构建MVC web应用| Pom |
    | spring-boot-starter-freemarker |使用FreeMarker 视图构建MVC web 应用的启动器| Pom |
    | spring-boot-starter-batch |对Spring Batch的支持| Pom |
    | spring-boot-starter-social-linkedin |用于为Spring Social LinkedIn的启动器| Pom |
    | spring-boot-starter-cache |用于对Spring 框架的缓存支持的启动器| Pom |
    | spring-boot-starter-data-solr |用于Spring Data Solr实现的 Apache Solr搜索平台的启动器| Pom |
    | spring-boot-starter-data-mongodb |用于MongoDB面向文档数据库和Spring Data MongoDB的启动器| Pom |
    | spring-boot-starter-jooq |使用jOOQ SQL关系数据库,替代 spring-boot-starter-data-jpa spring-boot-starter-jdbc | Pom |
    | spring-boot-starter-jta-narayana |Spring Boot Narayana JTA启动器| Pom |
    | spring-boot-starter-cloud-connectors |用于Spring Cloud 连接器的支持,可简化在Cloud Foundry 和 Heroku一样的云平台上服务连接。| Pom |
    | spring-boot-starter-jta-bitronix |使用Bitronix的JTA事务的启动器| Pom |
    | spring-boot-starter-social-twitter |用于Spring Social Twitter的启动器| Pom |
    | spring-boot-starter-data-rest |用于使用Spring Data REST暴露Spring Data 仓库到REST之外| Pom |
    除了应用启动器,以下启动器可用于添加 production ready 功能:

    表 13.2 Spring Boot 生产启动器
    spring-boot-starter-undertow 使用Undertow 作为内嵌的servlet容器, spring-boot-starter-tomcat 的替代方案 spring-boot-starter-jetty 使用jetty作为内嵌的servlet容器, spring-boot-starter-tomcat 的替代方案 spring-boot-starter-logging 日志使用Logback,默认的日志启动器 spring-boot-starter-tomcat 使用tomcat作为内嵌的servlet容器。 spring-boot-starter-web 使用的默认servlet容器启动器 spring-boot-starter-log4j2 使用Log4j2记录日志。 spring-boot-starter-logging 的替代方案

    14.2 放置应用的main类

    我们通常建议您放置您应用的main类在其他类之上的根目录包下。 @EnableAutoConfiguration 注解经常放在您的main上,它隐式地定义了某些项目的基本“搜索包”。例如:如果您正在编写一个JPA应用,则 @EnableAutoConfiguration 注解的类所在的包将会被用来搜索 @Entity 实体。

    使用根目录包还允许不需要指定 basePackage 属性,来使用 @ComponentScan 注解。如果你的main类在根目录包下,你也可以使用 @SpringBootApplication 注解。

    这是一个典型的布局:

    +- example +- myproject +- Application.java +- domain | +- Customer.java | +- CustomerRepository.java +- service | +- CustomerService.java +- web +- CustomerController.java

    Application.java 将声明main方法,以及基本的 @Configuration

    package com.example.myproject;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    @EnableAutoConfiguration
    @ComponentScan
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
    

    15. 配置类

    Sring Boot 提倡基于Java的配置。尽管可以使用XML源调用 SpringApplication.run(),但我们通常建议您的主要源是 @Configuration 类。通常,定义main方法的类是一个很好的候选人,作为主要的 @Configuration

    | 许多使用XML配置的Spring 配置示例已经发布在Internet。如果可能的话要始终尝试使用等效的基于Java的配置。搜索 enable* 注解,它可以是一个很好的起点。

    15.1 导入其他配置类

    您不需要将所有的 @Configuration 放在一个类中。 @Import 注解可以用来导入其他配置类。或者,你可以使用 @ComponentScan 注解自动提取所有的Spring 组件,包括 @Configuration 类。

    15.2 导入XML配置

    如果您绝对必须使用基于XML的配置,我们建议您仍然从 @Configuration 类开始。 然后,您可以使用额外的 @ImportResource 注解来加载XML配置文件。

    16. 自动配置

    Spring Boot 自动配置(auto-configuration)尝试基于您添加的jar依赖自动配置您的Spring应用程序。例如,如果 HSQLDB 在您的类路径上,并且您没有手动配置任何数据库连接bean,那么我们将自动配置一个内存数据库。

    您需要通过添加 @EnableAutoConfiguration @SpringBootApplication 注解到一个你 @Configuration 的类来选择加入自动配置。

    16.1 逐渐替换自动配置

    自动配置是非侵入性的,你可以在任何时候开始定义自己的配置去替换自动配置的特定的部分。例如,如果你添加自己的 DataSource bean,则默认的内嵌数据库支持将会退回。

    如果你想了解什么自动配置在当前存在应用,以及为什么,请使用 --debug 开关启动你的应用。这将启用调试日志级别给核心日志记录器一个选择,并将记录一个自动配置报告到控制台。

    16.2 禁用特定的自动配置

    如果您发现你不想要的特定自动配置正在应用,可以使用 @EnableAutoConfiguration 的exclude属性来禁用它们。

    import org.springframework.boot.autoconfigure.*;
    import org.springframework.boot.autoconfigure.jdbc.*;
    import org.springframework.context.annotation.*;
    @Configuration
    @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
    public class MyConfiguration {
    

    如果该类不在类路径上,则可以使用注解的 excludeName 属性,并指定完全限定名称来代替。 最后,您还可以通过 spring.autoconfigure.exclude 属性控制要排除的自动配置类列表。

    17. Spring Beans 和依赖注入

    您可以自由使用任何标准的Spring 框架技术来定义您的beans以及其注入的依赖。 为了简单起见,我们经常发现使用 @ComponentScan 找到你的bean,结合 @Autowired 构造函数注入效果很好。

    如果您按照上述建议(将应用程序类放在根包中)构建代码,则可以添加 @ComponentScan 而不使用任何参数。 所有应用程序组件(@Component@Service@Repository@Controller等)将自动注册为Spring Bean。

    以下是一个使用构造函数注入获取必需的 RiskAssessor bean的 @Service Bean的例子。

    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;
        // ...
    

    并且如果一个bean有一个构造函数,你可以省略 @Autowired

    @Service
    public class DatabaseAccountService implements AccountService {
        private final RiskAssessor riskAssessor;
        public DatabaseAccountService(RiskAssessor riskAssessor) {
            this.riskAssessor = riskAssessor;
        // ...
    

    18. 使用 @SpringBootApplication注解

    许多Spring Boot开发人员总是使用@Configuration@EnableAutoConfiguration@ComponentScan来标注它们的main类。 由于这些注释经常一起使用(特别是如果您遵循上述最佳实践),Spring Boot提供了一个方便的 @SpringBootApplication 替代方法。

    @SpringBootApplication 注解相当于使用@Configuration@EnableAutoConfiguration@ComponentScan及其默认属性:

    package com.example.myproject;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
    
    | @SpringBootApplication 还提供了别名来定制 @EnableAutoConfiguration @ComponentScan 的属性。

    19. 运行您的应用

    将应用程序打包成jar并使用内嵌的HTTP服务器的最大优点之一就是你可以像其他方式那样运行你的应用。 调试Spring Boot应用程序也很容易; 您不需要任何特殊的IDE插件或扩展。

    19.1 从一个IDE运行

    您可以从IDE运行一个Spring Boot应用如同一个简单的Java应用。然而,第一步你将需要导入你的项目。导入步骤取决于您的IDE和构建系统将有所变化。 大多数IDE可以直接导入Maven项目,例如Eclipse用户可以从 File 菜单中选择 Import…​ Existing Maven Projects

    如果您无法将项目直接导入到IDE中,则可以使用构建插件生成IDE元数据。 Maven包括 Eclipse IDEA 的插件; Gradle为 各种IDE 提供插件。

    | 如果你偶然运行了一个web 应用两次,将会看到一个“端口已在使用”的错误。STS用户可以使用 Relaunch (重新启动)按钮而不是运行,以确保任何现有实例已关闭。

    19.2作为一个打包应用运行

    如果你在使用Spring Boot Maven或Gradle插件创建一个可执行的jar,你可以使用 java -jar 运行你的应用。例如:

    $ java -jar target/myproject-0.0.1-SNAPSHOT.jar 
    

    它也可以以启用远程调试支持,运行一个打包应用。这允许你附加一个调试器到你的打包应用中:

    $ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
       -jar target/myproject-0.0.1-SNAPSHOT.jar
    

    19.3 使用Maven插件

    Spring Boot Maven插件包含一个 run 目标,可用于快速编译和运行应用程序。应用像在你的IDE中一样,运行在一个exploded 形式中:

    $ mvn spring-boot:run
    

    您可能还需要使用有用的操作系统环境变量:

    $ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M
    

    19.4 使用Gradle插件

    Spring Boot Gradle 插件也包含一个 bootRun 任务,用于将你的应用运行在一个 exploded 形式中。当你导入 spring-boot-gradle-plugin 后,这个 bootRun任务都会被添加:

    $ gradle bootRun
    

    您可能还需要使用有用的操作系统环境变量:

    $ export JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=128M
    

    19.5 热插拔

    由于Spring Boot应用只是普通的Java应用,所以JVM热插拔应该开箱即用。JVM热插拔可替的节码有些限制,为了更完整的解决方案,JRebel 或 Spring Loaded 可以被使用。spring-boot-devtools 模块也包含快速重新启动应用的支持。

    有关详细信息,请参阅下面第20章 开发者工具部分,以及Hot swapping “How-to”的内容。

    20. 开发者工具

    Spring Boot 包含一个额外的工具集,可以使应用开发体验更加愉快。spring-boot-devtools 模块可以包含在任何模块中,以提供额外的development-time特性。要包含devtools支持,只需添加模块依赖到你的构建中:

    Maven

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    

    Gradle

    dependencies {
        compile("org.springframework.boot:spring-boot-devtools")
    
    | 默认情况下重新打包档案不包含devtools。如果你想使用某些远程devtools特性,你需要禁用 excludeDevtools 构建属性去包含它。Maven 和 Gradle插件都支持该属性。

    20.1 默认属性

    Spring Boot 支持的几个库使用缓存来提高性能。 例如,模板引擎将缓存编译的模板,以避免重复解析模板文件。 此外,Spring MVC可以在服务静态资源时向响应中添加HTTP缓存头。

    虽然缓存在生产中是非常有利的,但它在开发过程中可能会产生反效果,阻止您看到刚刚在应用程序中进行的更改。 由于这个原因,spring-boot-devtools将默认禁用这些缓存选项。

    缓存项通常通过设置 application.properties 文件进行配置。例如,Thymeleaf 提供了 spring.thymeleaf.cache 属性。 spring-boot-devtools 模块将自动应用合理的 development-time 配置,而不是需要手动设置这些属性。

    20.2 自动重启

    使用 spring-boot-devtools 的应用,每当类路径下的文件改变时,将会自动重新启动。这在一个IDE中工作可能是一个有用的特性,因为它为代码更改提供了非常快的反馈循环。默认情况下,任何在类路径下指向一个文件夹的实体,将会被监控其改变。注意,某些资源比如静态资源和视图模版不需要重启应用。

    由于DevTools 监控类路径资源,所以触发重启的唯一方式是更新classpath。引起classpath被更新的方式取决于你正在使用的IDE。
    在Eclipse中,保存修改的文件将导致类路径被更新并触发重新启动。在IntelliJ IDEA中,构建项目(`Build→Make Project`)将具有相同的效果。
    
    | 在决定classpath下的一个实体改变后,是否应该触发重新启动时,DevTools 自动忽略名为 spring-boot , spring-boot-devtools , spring-boot-autoconfigure , spring-boot-actuator , spring-boot-starter 的项目。

    重新启动和重新加载
    Spring Boot提供重新启动技术,它通过使用两个类加载器工作的。 不改变的类(例如,来自第三方jar的)被加载到基类加载器中。 您正在积极开发的类被加载到重新启动类加载器中。 当应用程序重新启动时,重新启动类加载器将被丢弃,并创建一个新的类加载器。 这种方法意味着应用程序重新启动通常比“冷启动”快得多,因为基类加载器已经可用并且它加载的类很多(populated)。

    如果发现重新启动对于你的应用来说不够快,或遇到类加载问题,您可以考虑重新加载技术例如ZeroTurnaround的JRebel。 这些工作通过改写他们加载的类,使它们更适合重载。 Spring Loaded提供了另一个选项,然而它不支持尽可能多的框架,并且不是商业上支持的。

    20.2.1 排除资源

    某些资源在更改时不一定需要触发重新启动。例如,Thymeleaf 模版可以随时编辑。默认情况下,更改 /META-INF/maven /META-INF/resources /resources /static /public /templates 中的资源不会触发重新启动,但会触发实时重新加载。如果要自定义这些排除项,可以使用spring.devtools.restart.exclude属性。 例如,要仅排除/ static和/ public,您将设置以下内容:

    spring.devtools.restart.exclude=static/**,public/**
    
    20.2.2 监视其他路径

    当您对不在类路径中的文件进行更改时,可能需要重新启动或重新加载应用程序。 为此,请使用 spring.devtools.restart.additional-paths 属性来配置其他路径以监视更改。 您可以使用上述spring.devtools.restart.exclude 属性来控制附加路径下的更改是否会触发完全重新启动或只是实时重新加载

    20.2.3 禁用重新启动

    如果不想使用重新启动特性,可以使用 spring.devtools.restart.enabled 属性来禁用它。 在大多数情况下,您可以在 application.properties 中设置此项(这仍将初始化重新启动类加载器,但不会监视文件更改)。

    如果您需要完全禁用重新启动支持,例如, 因为它不适用于特定库,则需要在调用 SpringApplication.run(...) 之前设置System属性。 例如:

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApp.class, args);
    
    20.2.4 使用触发文件

    如果您使用的是不断编译已更改文件的IDE,那可能更喜欢仅在特定时间触发重新启动。 为此,您可以使用“触发文件”,这是一个特殊文件,当您要实际触发重新启动检查时,必须修改它。 更改文件只会触发检查,只有在Devtools检测到它必须执行某些操作时才会重新启动。 触发文件可以手动更新,也可以通过IDE插件更新。

    要使用触发器文件,请使用 spring.devtools.restart.trigger-file 属性。

    | 您可能希望将 spring.devtools.restart.trigger-file 设置为 全局设置 ,以使所有项目以相同的方式表现。

    20.2.5 自定义重新启动类加载器

    如上面的 Restart vs Reload 部分所述,重新启动功能是通过使用两个类加载器实现的。 对于大多数应用程序,此方法运行良好,但有时可能会导致类加载问题。

    默认情况下,IDE中的任何打开的项目将使用“重新启动”类加载器加载,任何常规 .jar 文件将使用“base”类加载器加载。 如果您在多模块项目上工作,并且不是每个模块都导入到IDE中,则可能需要自定义一些东西。 为此,您可以创建一个 META-INF/spring-devtools.properties 文件。

    spring-devtools.properties 文件可以包含前缀是 restart.exclude. restart.include. 的属性。 include 元素是应该被拉入“restart”类加载器的项目,而且“exclude”元素是应该向下推入“base”类加载器的项目。 属性的值是将应用于类路径的正则表达式模式。

    restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
    restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
    
    | 所有的 META-INF/spring-devtools.properties 将从classpath 被加载。你可以把文件打包到你的项目,或项目消耗的库中。

    20.2.6 已知限制

    重新启动功能不是工作的很好对于使用标准 ObjectInputStream 反序列化的对象。 如果需要反序列化数据,可能需要使用Spring的 ConfigurableObjectInputStream Thread.currentThread().getContextClassLoader() 组合使用。

    不幸的是,个别的第三方库在不考虑上下文类加载器的情况下反序列化。 如果您发现这样的问题,您需要向原始作者请求修复。

    20.3 实时重新加载

    spring-boot-devtools模块包含一个内嵌的LiveReload服务器,可以在资源更改时用于触发浏览器刷新。 LiveReload浏览器扩展程序可以从livereload.com免费提供给Chrome,Firefox和Safari。

    如果您不想在应用程序运行时启动LiveReload服务器,则可以将 spring.devtools.livereload.enabled 属性设置为 false

    | 你只能一次运行一个LiveReload服务器。 应用启动之前,请确保没有其他LiveReload服务器正在运行。 如果从IDE启动多个应用程序,则只有第一个应用程序将有LiveReload的支持。

    20.4 全局设置

    您可以通过向 $HOME 文件夹添加名为 .spring-boot-devtools.properties 的文件来配置全局devtools设置(请注意,文件名以“.”开头)。 添加到此文件的任何属性将应用到您的计算机上使用devtools的 所有 Spring Boot应用程序。 例如,总是使用触发器文件配置重新启动,您可以添加以下内容:

    ~/.spring-boot-devtools.properties.

    spring.devtools.reload.trigger-file=.reloadtrigger
    

    20.5 远程应用

    Spring Boot开发者工具不仅限于本地开发。 当运行远程应用时也可以使用几个功能。 远程支持是可选的,要启用它你需要确保 devtools 被包含在打包存档中:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!-- 译者注:排除属性设置为false,即把devtools在打包插件中-->
                    <excludeDevtools>false</excludeDevtools>
                </configuration>
            </plugin>
        </plugins>
    </build>
    

    然后你需要设置一个 spring.devtools.remote.secret 属性,例如:

    spring.devtools.remote.secret=mysecret
    
    | 在远程应用程序上启用 spring-boot-devtools 是一种安全隐患。 您绝不能在生产部署中启用它的支持。

    远程devtools支持分为两部分: 有一个接受连接的服务器端端点,还有一个您在IDE中运行的客户端应用。 当 spring.devtools.remote.secret 属性设置后,服务器组件将自动启用。但是客户端组件必须手动启动。

    20.5.1 运行远程客户端应用

    设计远程客户端应用旨在从IDE中运行。 您需要使用与正在连接的远程项目相同的类路径运行 org.springframework.boot.devtools.RemoteSpringApplication 。 传递给应用程序的非选项参数应该是您要连接到的远程URL。

    例如,如果您使用Eclipse或STS,并且有一个名为 my-app 的项目已部署到Cloud Foundry,则将执行以下操作:

  • Run 菜单选择 Run Configurations…​
  • 创建一个新的 Java Application "启动配置"
  • 浏览 my - app 项目
  • 使用 org.springframework.boot.devtools.RemoteSpringApplication 作为主类
  • 添加 https://myapp.cfapps.io (或任何您的远程URL) 到 Program arguments

    一个运行中的远程客户端将看起来像:

      .   ____          _                                              __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
     \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
      '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
     =========|_|==============|___/===================================/_/_/_/
     :: Spring Boot Remote :: 1.5.2.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)
    
  • | 如果需要使用代理访问远程应用程序,请配置 spring.devtools.remote.proxy.host spring.devtools.remote.proxy.port 属性。

    20.5.2 远程更新

    远程客户端将以与 本地重新启动 相同的方式监控你的应用类路径的更改。 任何更新的资源将被推送到远程应用,并且(如果需要)触发重新启动。 如果您正在使用您本地没有的云服务迭代功能,这可能会是相当有用的。 通常,远程更新和重新启动比完全重建和部署周期要快得多。

    20.5.3 远程调试通道

    在一个远程应用诊断问题时,Java远程调试非常有用。 不幸的是,当您的应用程序部署在数据中心之外时,并不总是可以启用远程调试。 如果您正在使用基于容器的技术(如Docker),远程调试也可能难以设置。

    为了帮助解决这些限制,devtools 支持基于HTTP的远程调试通道 ,远程客户端提供一个在端口8000的本地server,您可以连接远程调试器。 一旦建立连接后,调试信息通过HTTP被发送到远程应用。 如果要使用其他端口,可以使用 spring.devtools.remote.debug.local-port 属性进行设置。

    你需要确保远程应用启动时,已启用远程调试功能。通常可以通过配置 JAVA_OPTS 来实现。 例如,使用Cloud Foundry,您可以将以下内容添加到 manifest.yml 中:

    JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n" | 当使用IntelliJ IDEA的远程调试通道时,必须将所有断点配置为挂起线程而不是VM。 默认情况下,IntelliJ IDEA中的断点会挂起整个VM,而不是仅暂停触发断点的线程。 正在暂停的管理远程调试通道的线程有不想要的副作用,会导致调试会话冻结。 当使用IntelliJ IDEA的远程调试通道时,应将所有断点配置为挂起线程而不是VM。 有关详细信息,请参阅 IDEA-165769

    21. 为生产打包您的应用

    可执行的jar可用于生产部署。 由于它们是独立的,所以它们也非常适合基于云的部署。

    对于其他“生产就绪”功能,如健康,审计和测量REST或JMX端点; 考虑添加 spring-boot-actuator 。 有关详细信息,请参见 第五部分. Spring Boot 执行器: Production-ready 功能

    22. 接下来阅读什么

    随着你应该遵循的一些最佳实践,现在应该对如何使用Spring Boot 有一个很好的理解。您现在可以继续深入学习关于 Spring Boot 特性 具体内容,或者您可以跳过,去阅读关于Spring Boot“ 生产就绪 ”方面的内容。

    第三部分翻译完毕,继续阅读请移步到 这里