美文网首页
Spring Boot的使用

Spring Boot的使用

作者: 走过分叉路 | 来源:发表于2019-11-12 12:22 被阅读0次

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同一文件夹下的所有目录的变化都会被检测到。视图模板和静态资源这一类的资源的变化,不需要重新启动应用。

Restart的触发
因为DevTools检测的是classpath目录下的资源的变化,触发restart的唯一方式就是更新classpath。当然,更新的方式取决于你使用的IDE。在Eclipse中,保存一个修改过的文件就会更新classpath,触发restart。在IntelliJ IDEA中,编译项目有一样的效果(Build +→+ Build Project)。

image.png

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的检查。

这个文件的任何更新都会触发检查,但是只有DevTools检查到区别应用才会真正重启

触发文件的名称(不包含任何路径)作为spring.devtools.restart.trigger-file属性的值,这个文件必须在classpath下。如果是下面这样的目录结构: image.png

属性可以这样设置:

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

前缀固定,每个属性的key必须是唯一的。只要有规定的前缀,属性就能被读取。

image.png

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

如果在HOME/.config/spring-boot下没有找到devTools的配置文件,就会在HOME的root下找.spring-boot-devtools.properties文件。这让你可以跟那些不支持$HOME/.config/spring-boot的旧版本的Spring Boot应用共享配置。

image.png

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
方面的知识。

相关文章

网友评论

      本文标题:Spring Boot的使用

      本文链接:https://www.haomeiwen.com/subject/ouzybctx.html