(三)Spring Boot的使用 (翻译自Spring Boot官方教程文档)1.5.9.RELEASE

  • 查看本文英文文档,请点击 me
  • 本文将在对原英文文档进行翻译的基础上,结合作者动手实践一步步图文并茂展示给大家!
  • 小弟学识尚浅,若文章有不对的地方,请在评论区帮小弟指出,非常感谢!

第三部分 使用 Spring Boot

  • 本节将更详细地介绍如何使用Spring Boot。它涵盖了系统构建,自动配置以及如何运行应用程序等主题。我们还介绍了一些Spring Boot的最佳实践。虽然Spring Boot没有特别的特殊之处,(Spring Boot只是你可以使用的另一个Java库(jar)),但其中有一些建议,当你遵循时,会使你的开发过程变得更加容易一些。如果您刚刚开始使用Spring Boot,则可能需要先阅读入门指南,然后再深入本节。

13、系统构建

  • 强烈建议您选择支持依赖管理的构建系统,并且可以使用发布到“Maven Central”存储库的artifacts。我们建议您选择MavenGradle。Spring Boot可以与其他构建系统(例如Ant)一起工作,但是它们之间的兼容性并不是特别好。
13.1、依赖管理
  • Spring Boot的每个发行版都提供了一个支持的依赖列表。在实践中,您不需要为构建配置中(即在Pom.xml文件中)的任何这些依赖项提供一个版本(也就是可以省略version标签),因为Spring Boot正在为您进行管理(也就是Spring Boot 已经帮我们配置了)。当您升级Spring Boot本身(也就是切换到更高版本的Spring Boot)时,这些依赖关系也将以一致的方式进行升级。

    如果你觉得这是必要的,你仍然可以指定一个版本并覆盖Spring Boot的建议。

  • 该列表包含了你能使用 Spring Boot 的所有 Spring 模块和一系列第三方类库。该列表可以作为标准物料清单spring-boot-dependencies)提供,也可以为MavenGradle提供额外的专用支持。

    Spring Boot的每个版本都与一个Spring Framework的基础版本相关联,因此我们强烈建议您不要自行指定其版本。

13.2、Maven
  • Maven用户可以从spring-boot-starter-parent项目中继承,以获得相应的默认值。 父项目提供以下功能:
    1. Java 1.6作为默认的编译器级别。
    2. UTF-8源码编码。
    3. 一个依赖管理系统,因此你可以针对公共的依赖省略<version>标签,进而从spring-boot-dependencies POM中继承。
    4. 优雅的资源过滤
    5. Sensible plugin configuration (exec plugin, surefire, Git commit ID, shade).
    6. application.propertiesapplication.yml中的配置进行资源过滤(其实就是maven打包时指定哪些文件要过滤,不参与打包),包括特定于配置文件的文件(例如application-foo.propertiesapplication-foo.yml
  • 最后一点:由于默认配置文件接受Spring样式占位符($ {...}),Maven过滤被改为使用@ .. @占位符(您可以用Maven属性resource.delimiter覆盖)。
13.2.1、继承父starter工程来创建 Spring Boot
  • 要将项目配置为从spring-boot-starter-parent中继承,只需设置<parent>
    <!-- Inherit defaults from Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    复制代码

    您只需要在上面parent依赖项上指定Spring Boot版本号。 如果您导入更多的starter,则可以安全地省略版本号(即<version>)。

  • 通过该设置,您还可以通过在自己的项目中重写属性来覆盖各个依赖项。 例如,要升级到另一个Spring Data发行版,您需要将以下内容添加到您的pom.xml中。
    <properties>
        <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
    </properties>
    复制代码

    检查spring-boot-dependencies pom以获取支持的属性列表。

13.2.2、不继承父starter工程来创建 Spring Boot
  • 并不是所有人都喜欢使用继承自spring-boot-starter-parent POM的方式来使用 Spring Boot,可能你有自己的标准(也就是自定义配置)或者你单单就喜欢显式地声明所有的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>1.5.9.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    复制代码
  • 如上所述,该设置不允许您使用属性覆盖单个依赖项。 为了达到同样的结果,你需要在spring-boot-dependencies标签(也就是pom文件的dependencies标签)之前在项目的dependencyManagement中添加一个条目。 例如,要升级到另一个Spring Data发行版,您需要将以下内容添加到您的pom.xml中。
    <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>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.5.9.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    复制代码

    在上面的例子中,我们指定了一个BOM(物料清单,这里指的是pom.xml),但是任何依赖类型都可以被覆盖。

13.2.3、改变 Java 版本
  • spring-boot-starter-parent选择相当保守的Java兼容性(指的是上面说的 Java 6)。 如果您想遵循我们的建议并使用较新的Java版本,则可以添加一个java.version属性:
    <properties>
        <java.version>1.8</java.version>
    </properties>
    复制代码
13.2.4、使用 Spring Boot Maven 插件
  • Spring Boot包含一个Maven插件,可以将项目打包为可执行的jar文件。 如果你想使用它,请将插件添加到<plugins>部分:
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    复制代码

    如果你使用Spring Boot的起始parent POM,你只需要添加插件,除非你想改变在父代中定义的配置,否则不需要进行配置。

13.3、Gradle
  • Gradle用户可以直接在他们的dependencies部分导入starters。 与Maven不同的是,没有super parent可以导入来共享某些配置。
    repositories {
        jcenter()
    }
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web:1.5.9.RELEASE")
    }
    复制代码
  • spring-boot-gradle-plugin也是可用的,并提供了创建可执行jar和从源项目运行项目的任务。 它还提供依赖管理,除其他功能外,还允许您省略由Spring Boot管理的任何依赖项的版本号:
    plugins {
        id 'org.springframework.boot' version '1.5.9.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
  • 主要讲如何使用Ant进行构建,由于前面说到Spring Boot兼容不太好,所以兴趣的可以点击此处
13.5、Starters
  • starters是一系列可以引进你项目的依赖描述符(dependency descriptors我觉得其实就是一些jar包,里边的pom.xml文件帮我们做了某些配置而已)。您可以得到所需要的所有关于Spring及其相关技术的一站式服务,无需搜索示例代码,也不需要粘贴大量依赖描述符(传统我们pom.xml都要引入很多的<dependency/>)。例如,如果你想开始使用SpringJPA来访问数据库,只需在你的项目中加入spring-boot-starter-data-jpa依赖项,你就可以开始编码了哟~
  • starters包含了许多你需要快速运行一个项目并传递依赖项的依赖。(即它会自动传递依赖)。
    为什么叫starters这个名字呢?

    所有的官方starter都遵循这个spring-boot-starter-*命名规范,*代表某一具体的应用(比如web应用程序)。这种命名结构旨在帮助您找到某一具体的starter。许多IDE中的Maven集成允许您按名称搜索依赖项。例如,安装某一具体的Eclipse``STS插件后,只需在POM编辑器中点击ctrl-space,然后键入“spring-boot-starter”获取完整列表。正如创建自己的starter中所解释的,第三方starter不应该以spring-boot为开始,因为它是为官方Spring Boot工件(artifacts)保留的。一个表示acme应用的第三方starter的命名可能就是acme-spring-boot-starter

  • 以下就是 Spring Boot 在org.springframework.boot包下定义的一些starter
    表格13.1 Spring Boot应用程序starters
    名称描述Pom
    spring-boot-starter核心starter,包括自动配置支持,日志记录和YAMLPOM
    spring-boot-starter-activemq使用Apache ActiveMQ进行JMS消息传递POM
    spring-boot-starter-amqp使用 Spring AMQP和Rabbit MQPOM
    spring-boot-starter-aop使用Spring AOP和AspectJ进行面向方面编程的starterPOM
    spring-boot-starter-artemis使用Apache Artemis进行JMS消息传递POM
    spring-boot-starter-batch使用Spring BatchPOM
    spring-boot-starter-cache使用Spring框架的缓存支持POM
    spring-boot-starter-cloud-connectors使用Spring Cloud连接器的starter,可简化Cloud Foundry和Heroku等云平台中的服务连接POM
    spring-boot-starter-data-cassandra使用Cassandra分布式数据库和Spring Data CassandraPOM
    spring-boot-starter-data-couchbase使用面向文档的数据库Couchbase和Spring Data CouchbasePOM
    spring-boot-starter-data-elasticsearch使用搜索、分析引擎Elasticsearch和Spring Data ElasticsearchPOM
    spring-boot-starter-data-gemfire使用分布式数据存储GemFire和Spring Data GemFirePOM
    spring-boot-starter-data-jpa使用带有Hibernate的Spring Data JPAPOM
    spring-boot-starter-data-ldap使用Spring Data LDAPPOM
    spring-boot-starter-data-mongodb使用面向文档的数据库MongoDB和Spring Data MongoDBPOM
    spring-boot-starter-data-neo4j使用图形数据库Neo4j和Spring Data Neo4jPOM
    spring-boot-starter-data-redis使用带有Spring Data Redis和Jedis客户端的Redis键值数据存储POM
    spring-boot-starter-data-restStarter for exposing Spring Data repositories over REST using Spring Data RESTPOM
    spring-boot-starter-data-solr结合Spring Data Solr使用Apache Solr 搜索平台POM
    spring-boot-starter-freemarker使用FreeMarker视图构建MVC Web应用程序POM
    spring-boot-starter-groovy-templates使用Groovy模板视图构建MVC Web应用程序POM
    spring-boot-starter-hateoas使用Spring MVC和Spring HATEOAS构建基于超媒体的RESTful Web应用程序POM
    spring-boot-starter-integration使用Spring集成POM
    spring-boot-starter-jdbc将JDBC与Tomcat JDBC连接池配合使用POM
    spring-boot-starter-jersey使用JAX-RS和Jersey构建RESTful Web应用程序的starter。是Spring-Boot-Starter-Web的另一种选择POM
    spring-boot-starter-jooq使用jOOQ访问SQL数据库的starterspring-boot-starter-data-jpaspring-boot-starter-jdbc的替代方案POM
    spring-boot-starter-jta-atomikos使用Atomikos的JTA事务POM
    spring-boot-starter-jta-bitronix使用Bitronix的JTA事务POM
    spring-boot-starter-jta-narayanaSpring Boot Narayana JTA StarterPOM
    spring-boot-starter-mail使用Java Mail和Spring Framework支持的电子邮件发送POM
    spring-boot-starter-mobile使用Spring Mobile构建Web应用程序POM
    spring-boot-starter-mustache使用Mustache视图构建MVC Web应用程序POM
    spring-boot-starter-security使用Spring SecurityPOM
    spring-boot-starter-social-facebook使用Spring社交FacebookPOM
    spring-boot-starter-social-linkedin使用Spring社交LinkedInPOM
    spring-boot-starter-social-twitter使用Spring社交twitterPOM
    spring-boot-starter-testStarter用于测试包含JUnit,Hamcrest和Mockito等库的Spring Boot应用程序POM
    spring-boot-starter-thymeleaf使用Thymeleaf视图构建MVC Web应用程序POM
    spring-boot-starter-validation通过Hibernate Validator使用Java Bean验证POM
    spring-boot-starter-web用于构建Web的starter,包括使用Spring MVC的RESTful应用程序。 使用Tomcat作为默认的嵌入容器POM
    spring-boot-starter-web-services使用Spring Web ServicesPOM
    spring-boot-starter-websocket使用Spring Framework的WebSocket支持构建WebSocket应用程序POM
  • 除了应用程序starter之外,还可以使用以下starter来做好相应的生产准备:
    表格13.2 Spring Boot 产品starters
    名称描述POM
    spring-boot-starter-actuator使用具有生产准备功能的Spring Boot的执行器,可以帮助您监控和管理您的应用程序POM
    spring-boot-starter-remote-shell使用CRaSH远程shell通过SSH监视和管理您的应用程序。 自1.5以来已弃用POM
  • 最后,Spring Boot还包括一些可以用来排除或交换特定技术门面的starters
    表格13.3 Spring Boot 技术starters
    名称描述POM
    spring-boot-starter-jetty使用Jetty作为嵌入式servlet容器的starterspring-boot-starter-tomcat的替代方案POM
    spring-boot-starter-log4j2使用Log4j2进行日志记录的starterspring-boot-starter-logging 的替代方法POM
    spring-boot-starter-logging使用Logback进行日志记录。 默认日志starterPOM
    spring-boot-starter-tomcat使用Tomcat作为嵌入式servlet容器的starterspring-boot-starter-web使用的默认servlet容器starterPOM
    spring-boot-starter-undertow使用Undertow作为嵌入式servlet容器的starterspring-boot-starter-tomcat的替代方案POM

    有关其他社区贡献者的列表,请参阅GitHub上的spring-boot-starters模块中的README文件

14、结构化你的代码

  • Spring Boot不需要任何特定的代码布局,但是,有一些最佳实践可以帮助。
14.1、使用“默认的”package
  • 当一个类没有声明package时,我们一般会认为这个类位于“默认包”中。通常不鼓励使用“默认软件包”,且应该避免使用“默认软件包”。对于使用@ComponentScan@EntityScan@SpringBootApplication注释的Spring Boot应用程序来说,使用“默认包”可能会导致特定的问题,因为每个jar的每个类都将被读取。(这里其实说的是Spring Boot会进行组件、实体、包的扫描@ComponentScan

    我们建议您遵循Java推荐的软件包命名约定,并使用反向域名(例如com.example.project)。

14.2、定位我们的主应用程序类
  • 我们通常建议您将主应用程序类放在其他类的根包中。@EnableAutoConfiguration注释通常放在主类上,并且它隐含地为某些项目定义了一个基本的“搜索包”。例如,如果您正在编写JPA应用程序,则@EnableAutoConfiguration注释类的包将用于搜索@Entity条目。
  • 使用根包也允许使用@ComponentScan注释而不需要指定basePackage属性。如果您的主类位于根包中,也可以使用@SpringBootApplication注释。
  • 这是一个典型的项目结构:
    com
        +- 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、配置类

  • Spring Boot支持基于Java的配置。尽管可以使用XML源调用SpringApplication.run(),我们通常建议您的主要来源是@Configuration类。通常,定义main方法的类也是@Configuration的一个首选。

    在互联网上已经发布了许多使用XML配置的Spring配置示例。 如果可能,请始终尝试使用基于Java的等效配置。 搜索Enable*注释可以是一个很好的起点。

15.1、导入额外的配置类
  • 你不需要把你所有的@Configuration放到一个类中。@Import注解可用于导入其他配置类。或者,您可以使用@ComponentScan自动获取所有Spring组件,包括@Configuration类。
15.2、带入XML配置
  • 如果您绝对必须使用基于XML的配置,我们建议您仍以@Configuration类开头。然后您可以使用额外的@ImportResource注解来加载XML配置文件。

16、自动配置

  • Spring Boot自动配置会尝试根据您添加的jar依赖项自动配置您的Spring应用程序。例如,如果HSQLDB在您的类路径中,并且您没有手动配置任何数据库连接Bean,那么我们将自动配置一个内存数据库。
  • 您需要通过将@EnableAutoConfiguration@SpringBootApplication注释添加到其中一个@Configuration类来选择自动配置。

    您应该只添加一个@EnableAutoConfiguration注释。 我们通常建议您将其添加到您的主要@Configuration类。

16.1、逐渐取代自动配置
  • 自动配置是非侵入式的,您可以随时开始定义自己的配置来替换自动配置的特定部分。如果添加自己的DataSource Bean,则默认的嵌入式数据库支持将失效。
  • 如果您需要了解当前正在应用的自动配置,以及为什么?那么请使用--debug参数启动您的应用程序(也就是debug模式启动应用程序)。 这将启用选择核心记录器的调试日志,并将自动配置报告记录到控制台。
16.2、禁用特定的自动配置
  • 如果您发现正在应用您不需要的特定自动配置类,则可以使用@EnableAutoConfigurationexclude属性来禁用它们。
    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属性(这个主要在property文件中声明)来控制自动配置类的列表。

    你能在注解级别和property配置文件级别设置警用自动相应的配置。(注:一个类声明了@Configuration注解则表示该类是一个配置类,可以被禁用)

17、Spring Bean 和 依赖注入

  • 您可以自由使用任何标准的Spring框架技术来定义您的bean及其注入的依赖关系。 为了简单起见,我们经常发现使用@ComponentScan来查找bean,并结合使用@Autowired构造函数注入效果最好。
  • 如果按上面的建议构建代码(在根包中查找应用程序类),则可以添加@ComponentScan而不带任何参数。 所有的应用程序组件(@Component@Service@Repository@Controller等)都将被自动注册为Spring Bean
  • 这里是一个示例@Service Bean,它使用构造函数注入来获得必需的RiskAssessor 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;
        //此处省略了@Autowired
        public DatabaseAccountService(RiskAssessor riskAssessor) {
            this.riskAssessor = riskAssessor;
        }
        // ...
    }
    复制代码
  • 请注意,如何使用构造函数注入允许riskAssessor字段被标记为final,表明它不能被随后更改。

18、使用@SpringBootApplication注解

  • 许多Spring Boot开发人员总是使用@Configuration@EnableAutoConfiguration@ComponentScan注解其主类。由于这些注释经常一起使用(特别是如果您遵循以上最佳实践),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插件或扩展。

    本节仅介绍基于jar的打包。如果您选择将应用程序打包为war文件,则应参考您的服务器和IDE文档。

19.1、从IDE中运行
  • 你可以像普通Java应用程序一样在IDE中运行Spring Boot 应用。但是,首先你需要将项目导入IDE中,大多数IDE可以直接导入Maven项目,例如在EclipseFile -> Import -> Existing Maven Projects
  • 如果不能直接将项目导入IDE,则可以使用构建插件生成IDE元数据。 Maven包含EclipseIDEA的插件; Gradle也为各种IDE提供了各种插件

    如果您不小心运行了两次Web应用程序,则会看到“端口已被使用Port already in use”错误。 STS用户可以使用"Relaunch"按钮而不是"Run"来确保关闭任何现有的实例。

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中一样。

    $ mvn spring-boot:run

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

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

19.4、使用Gradle插件
  • Spring Boot Gradle插件还包含一个bootRun任务,可用于以分解形式运行您的应用程序。 无论何时导入spring-boot-gradle-plugin,都会添加bootRun任务:

    $ gradle bootRun

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

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

19.5、热插拔
  • 因为Spring Boot仅仅是普通的Java应用程序,JVM热插拔应该是开箱即用的。JVM热交换在某种程度上受限于它可以替换的字节码,为了获得更完整的解决方案,可以使用JRebelSpring Loaded项目。

20、开发者工具

  • Spring Boot包含一组额外的工具,可以使应用程序开发体验更愉快。 spring-boot-devtools模块可以包含在任何项目中以提供额外的开发时间功能。 要包含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")
    }
    复制代码

    运行完整打包的应用程序时,开发者工具会自动禁用。 如果您的应用程序是使用java -jar方式启动的,或者如果它是使用特殊的类加载器启动的,那么它就被认为是“生产应用程序”。 将依赖关系标记为可选的是一种最佳实践,可以防止devtools通过项目传递到其他模块。 Gradle不支持optional的依赖关系,因此您可能希望在此期间看看propdeps插件

    重新打包的archives在默认情况下不包含devtools。 如果您想使用某些远程devtools功能,则需要禁用excludeDevtools构建属性以包含它。 该属性支持Maven和Gradle插件。

19.1、属性默认值
  • Spring Boot支持的一些库使用缓存来提高性能。 例如,模板引擎将缓存已编译的模板,以避免重复解析模板文件。 另外,Spring MVC可以在服务静态资源时将HTTP缓存头添加到响应中。
  • 虽然缓存在生产中非常有益,但在开发过程中可能会产生反作用,使您无法看到应用程序中刚刚做出的更改。 由于这个原因,spring-boot-devtools默认会禁用这些缓存选项。
  • 缓存选项通常由您的application.properties文件中的设置进行配置。 例如,Thymeleaf提供了spring.thymeleaf.cache属性。 而不需要手动设置这些属性,spring-boot-devtools模块将自动应用合理的开发配置。

    有关应用的属性的完整列表,请参阅DevToolsPropertyDefaultsPostProcessor

20.2、自动重启
  • 使用spring-boot-devtools的应用程序将在类路径上的文件发生更改时自动重启。 在IDE中工作时,这是一个非常有用的功能,因为它为代码更改提供了一个非常快速的反馈循环。 默认情况下,将监视指向文件夹的类路径中的任何条目以进行更改。 请注意,某些资源(如静态资产和视图模板)不需要重新启动应用程序

    触发重启

    由于DevTools监视类路径资源,触发重启的唯一方法是更新类路径。 导致类路径更新的方式取决于您使用的IDE。 在Eclipse中,保存修改后的文件将导致类路径更新并触发重启。 在IntelliJ IDEA中,构建项目(Build - > Make Project)将具有相同的效果。

    您也可以通过受支持的构建插件(即Maven和Gradle)启动您的应用程序,只要启用了分叉功能,因为DevTools需要隔离的应用程序类加载器才能正常运行。 当Gradle和Maven在类路径中检测到DevTools时,默认会这样做。

    与LiveReload一起使用时,自动重新启动的效果非常好。 详情请参阅下文。 如果使用JRebel,自动重新启动将被禁用,以支持动态类重新加载。 其他devtools功能(如LiveReload和属性覆盖)仍然可以使用。

    DevTools依靠应用程序上下文的关闭挂钩在重新启动期间关闭它。 如果您禁用了关闭挂钩(SpringApplication.setRegisterShutdownHook(false)),它将无法正常工作。

    当确定类路径上的条目在更改时会触发重新启动时,DevTools会自动忽略名为spring-boot,spring-boot-devtoolsspring-boot-autoconfigurespring-boot-actuatorspring-boot-starter的项目。

    DevTools需要自定义ApplicationContext使用的ResourceLoader:如果你的应用程序已经提供了一个,它将被打包。 不支持直接覆盖ApplicationContext上的getResource方法。

    重启(restart) vs 重新加载(reload)

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

    如果您发现重新启动对于您的应用程序来说不够快,或者遇到类加载问题,则可以考虑从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/**

    如果要保留这些默认值并添加其他排除项,请改为使用spring.devtools.restart.additional-exclude属性。

20.2.2、监视额外的其他路径(Watching additional paths)
  • 您可能希望当更改不在类路径中的文件时重新启动或重新加载应用程序。 为此,请使用spring.devtools.restart.additional-paths属性来配置其他路径以监视更改。 您可以使用上述的spring.devtools.restart.exclude属性来控制额外路径下的更改是否会触发完全重新启动或仅实时重新加载。
20.2.3、禁用重启
  • 如果您不想使用重新启动功能,则可以使用spring.devtools.restart.enabled属性将其禁用。 在大多数情况下,你可以在你的application.properties中设置它(这将仍然初始化重启类加载器,但它不会监视文件的变化,也就是只要你重新启动了Spring Boot应用程序,都会冲洗初始化一个新的重启类加载器,上文也提到了)。(注意重新启动关闭后启动的区别)
  • 如果您需要完全禁用重新启动支持(不会有重新启动的功能,也就不会再初始化重启类加载器了哟~),例如,因为它不适用于特定的库,则需要在调用SpringApplication.run(...)之前设置System属性。 例如:
    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApp.class, args);
    }
    复制代码
20.3.4、使用触发器文件
  • 如果您使用连续编译已更改文件的IDE,则可能只希望在特定时间触发重新启动。 要做到这一点,你可以使用“触发文件”,这是一个特殊的文件,当你想要实际触发重启检查时,必须修改它。 只更改文件会触发检查,只有Devtools检测到必须执行某些操作时才会重新启动。 触发文件可以手动更新,也可以通过IDE插件进行更新。
  • 要使用触发器文件,请使用spring.devtools.restart.trigger-file属性。

    您可能需要将spring.devtools.restart.trigger-file设置为全局设置,以便所有项目的行为方式相同

20.3.5、自定义重启类加载器
  • 正如上面“重新启动vs重新加载”一节所述,重新启动功能是通过使用两个类加载器(一个基类,一个重启类)来实现的。 对于大多数应用程序来说,这种方法运行良好,但有时候会导致类加载问题。

  • 默认情况下,IDE中的任何打开的项目都将使用“重启”类加载器加载,任何常规的.jar文件都将使用“基本”类加载器加载。 如果您使用多模块项目,而不是将每个模块导入到IDE中,则可能需要自定义项目。 要做到这一点,你可以创建一个META-INF/spring-devtools.properties文件。

  • spring-devtools.properties文件可以包含restart.excluderestart.include前缀属性。include元素是应该被拉入到“重启”类加载器中的项目,排除元素是应该被下推到“基本”类加载器中的项目。 该属性的值是一个将应用于类路径的正则表达式模式。

  • 比如:

    restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
    restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
    复制代码

    所有的属性key(这里指上面的companycommonlibs)必须是唯一的。 只要属性以restart.includerestart.exclude开头的都将被考虑。

    所有类路径中的META-INF/spring-devtools.properties都将被加载。 您可以将文件打包到项目中,也可以打包到项目使用的库中。

20.3.6、已知的限制
  • 对于使用标准ObjectInputStream进行反序列化的对象,重新启动功能无法正常工作。 如果需要反序列化数据,则可能需要将Spring的ConfigurableObjectInputStreamThread.currentThread().getContextClassLoader()一起使用。
  • 不幸的是,有些第三方库反序列化,而不考虑上下文类加载器。 如果您发现这样的问题,您需要向原作者请求修复。
20.3、LiveReload(一个内置服务器)
  • spring-boot-devtools模块包含一个嵌入式LiveReload服务器,当资源发生变化时,可用于触发浏览器刷新。 LiveReload浏览器扩展可从livereload.com的Chrome,Firefox和Safari免费获得。
  • 如果您不想在应用程序运行时启动LiveReload服务器,则可以将spring.devtools.livereload.enabled属性设置为false

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

20.4、全局配置
  • 您可以通过将一个名为.spring-boot-devtools.properties的文件添加到您的$HOME文件夹来配置全局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>
                    <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。 传递给应用程序的非选项(non-option)参数应该是您要连接到的远程URL。
  • 例如,如果您使用的是Eclipse或STS,并且您已经将一个名为my-app的项目部署到了Cloud Foundry,则可以执行以下操作:
    1. Run菜单中选择Run Configurations…​
    2. 创建一个新的Java Application"launch configuration"。
    3. 浏览my-app项目。
    4. 使用org.springframework.boot.devtools.RemoteSpringApplication作为主类。
    5. https://myapp.cfapps.io添加到Program arguments(或任何远程URL)。
  • 正在运行的远程客户端将如下所示:
      .   ____          _                                              __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
     \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
      '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
     =========|_|==============|___/===================================/_/_/_/
     :: Spring Boot Remote :: 1.5.9.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.secret属性并将其传递给服务器进行身份验证。

  • 总是建议使用https://作为连接协议,以便流量被加密且密码不能被拦截!
  • 如果您需要使用代理来访问远程应用程序,请配置spring.devtools.remote.proxy.hostspring.devtools.remote.proxy.port属性。
20.5.2、远程更新
  • 远程客户端将以与本地重启相同的方式监视您的应用程序类路径的更改。 任何更新的资源将被推送到远程应用程序,并(如果需要)触发重新启动。 如果您正在迭代使用您本地没有的云服务的功能,这可能会非常有帮助。 通常远程更新和重新启动比完整的重建和部署周期快得多。

    只有远程客户端正在运行时才会监视文件。 如果在启动远程客户端之前更改文件,则更新操作不会将其推送到远程服务器。

20.5.3、远程调试隧道
  • Java远程调试在诊断远程应用程序的问题时非常有用。 不幸的是,当您的应用程序部署在数据中心之外时,并不总是可以启用远程调试。 如果您使用基于容器的技术(例如Docker),则远程调试也可能会非常棘手。

  • 为了帮助解决这些限制,devtools支持通过HTTP隧道传输远程调试流量。 远程客户端在端口8000上提供本地服务器,您可以将其附加到远程调试器。 建立连接后,调试流量将通过HTTP发送到远程应用程序。 如果你想使用不同的端口,你可以使用spring.devtools.remote.debug.local-port属性。

  • 您需要确保您的远程应用程序在启用远程调试的情况下启动。 这通常可以通过配置JAVA_OPTS来实现。 例如,使用Cloud Foundry,您可以将以下内容添加到您的manifest.yml中:

    ---
    env:
        JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n"
    复制代码

    请注意,您不需要将address=NNNN选项传递给-Xrunjdwp。 如果省略,Java将简单地选取一个随机空闲端口。

    通过Internet调试远程服务可能会很慢,您可能需要增加IDE中的超时时间。 例如,在Eclipse中,您可以选择JavaPreferences…``Debug并将debug timeout(ms)更改为更合适的值(在大多数情况下,60000的效果很好)。

    在IntelliJ IDEA中使用远程调试通道时,必须将所有断点配置为挂起线程而不是VM。 默认情况下,IntelliJ IDEA中的断点会暂停整个虚拟机,而不是仅挂起遇到断点的线程。 这具有暂停管理远程调试通道的线程的不良副作用,导致您的调试会话冻结。 在IntelliJ IDEA中使用远程调试通道时,应将所有断点配置为挂起线程而不是VM。 请参阅IDEA-165769了解更多详情。

21、打包您的生产应用程序

  • 可执行的jars可用于生产部署。 由于它们是独立的,因此它们也非常适合基于云的部署。
  • 对于额外的“生产就绪”功能,如健康,审计和度量REST或JMX端点; 考虑加入spring-boot-actuator。 有关详细信息,请参阅第五部分“spring-boot-actuator:生产就绪功能” 。

22、接下来读什么?

  • 您现在应该对如何使用Spring Boot以及您应该遵循的一些最佳实践有很好的理解。 您现在可以继续深入了解特定的Spring Boot功能,或者可以跳过并阅读Spring Boot的“生产就绪”部分。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值