spring boot官方文档 2.2.6 Using Spring Boot

相关文章spring boot官方文档 2.2.6 Getting Started.


这部分讲解更多的关于使用springboot的细节,它包括:构建项目(build systems),自动配置( auto-configuration)以及如何运行应用。也包含一些练习,这个相当于一个工具文档,用于查阅

1. Build Systems,构建项目

强烈建议选择一个支持依赖管理( dependency management )的项目构建工具,可以发布到maven 中心仓库 ,推荐选择 maven或者Gradle 也可以选择Ant,但是支持性没有maven或者Gradle 好

1.1. Dependency Management 依赖管理

每一版的springboot 都提供了它支持的依赖列表,在配置依赖的时候,不需要提供版本设置,因为springboot 已经为你管理了,升级springboot版本的时候,依赖管理也会对应的升级

TIP:如果需要,也可以指定一个版本,覆盖springboot推荐的版本;
依赖列表几乎包括了所有可能使用的spring 模板,和一些第三方的库,可以通过maven或者 Gradle 方式添加

Note:每个版本的Spring Boot 都是关联一个基本版本的Spring 框架,极度推荐不要覆盖Spring的版本

1.2. Maven

使用maven的方式,可以先查看 spring-boot-starter-parent 里面包含的内容
java 1.8 以及默认的编译级别
UTF-8 的编码格式
在pom文件中包含管理常见依赖版本的依赖管理片段,这个依赖管理使得在引入依赖额时候,可以省略版本信息
一个带有 id 的打包执行器
智能的 资源过滤
合理的插件管理
合理的资源过滤,例如(application.properties and application.yml)特定 的配置文件
注意:自从 Spring 的 application.properties 和 application.yml 能使用占位符 ${} ,Maven的过滤就变成了 @…@ 的方式,(可以设置 resource.delimiter 这个参数,来设置自己想要的值)

1.2.1. Inheriting the Starter Parent

为了让项目继承自 spring-boot-starter-parent 需要引入下面的starter

<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
</parent>

注意:在这个依赖中,需要注意的是 Spring Boot 的版本,在引入其他的starter 的时候,最后省略版本号

上面配置之后,也可以指定单个依赖的版本

<properties>
    <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

1.2.2. Using Spring Boot without the Parent POM

如果不想使用 spring-boot-starter-parent ,但是还是想用依赖管理(但是没有插件管理),可以使用 scope=import dependency,像下面这样

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

上面的示例不可以通过 property 覆盖单独的依赖,所以,为了设置版本,需要在依赖管理里面加一个实体,例如

<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.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

1.2.3. Using the Spring Boot Maven Plugin 使用 Spring Boot 的maven插件

SpringBoot提供了一个 Maven插件,可以把项目打包成一个可执行的jar文件,添加插件到里面

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

如果想用 Spring Boot starter 的父类的pom,只需要添加插件即可,不需要配置,除非你需要改变原来父类定义的配置

1.3. Gradle

1.4. Ant

1.5. Starters

Starter 是一系列依赖的集合,可以一站式的直接使用 所有的Spring及其相关的技术,不需要关注示例代码,也不需要复制粘贴许多其他的依赖(简而言之就是引入starter就够了),例如,如果想用 Spring 和JPA来连接数据库,只要引入一个 spring-boot-starter-jpa 的依赖到项目即可。
starter包含了构建项目的一系列依赖

starter 命名
spring-boot-starter-*
第三方的starter命名:是以第三方的项目名称开头的,如:一个第三方的starter project 项目叫做 thirdpartyproject 那么对应的 starter 命名应该是 thirdpartyproject -spring-boot-starter

下面是springboot提供的starter列表
In addition to the application starters, the following starters can be used to add production ready features:

Finally, Spring Boot also includes the following starters that can be used if you want to exclude or swap specific technical facets:

  1. Structuring Your Code
    spring boot不要求特定的代码格式,但是下面有一些经验

2.1. Using the “default” Package

当一个类没有写在某一个包里面的时候,应该包含在 “default package” 里面,不推荐使用默认的包,这样可能会引起一些问题,当使用 @ComponentScan, @ConfigurationPropertiesScan, @EntityScan, or @SpringBootApplication 这些注解的时候,因为每个jar包下面的每个class 都会被扫描。
推荐使用 com.example.project 的包结构

2.2. Locating the Main Application Class(定位主应用类)

就是标识应用的入口
推荐在 root package 下面放置 主类,而非其他的包,@SpringBootApplication注解需要放在主类上,这个注解含蓄的定义了一个基本的包扫描机制,扫描特定的项,(大致意思就是说,加了这个注解的类,会自动的扫描这个包及其子包下面的所有的加了注解的类,让spring管理)
TIP:如果不想使用 @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 会使用 @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. Configuration Classes(配置类)

Spring Boot支持基于Java的配置,虽然极有可能使用SpringApplication 和 xml 的方式来配置资源,但是还是推荐把主要的资源整合成为一个 单独的带有 @Configuration 注解的配置类。通常有 main 方法的类是比较好的加 @Configuration 的选择

这里有疑问?????????????????
这里的意思是推荐在有SpringApplication 的地方加一个 @Configuration ,让它作为配置类吗???
2020年4月17日11:13:01

TIP
在想配置什么的时候,想到 Enable* 注解

3.1. Importing Additional Configuration Classes

你不需要把所有的配置(@Configuration)都放在一个类里面,@Import注解可以注入其他的配置类,也可以通过 @ComponentScan 在自主的扫描所有的Spring组件(包括@Configuration类)

3.2. Importing XML Configuration

如果必须使用xml配置,还是推荐写一个 配置类(@Configuration),可以使用 @ImportResource注解加载 xml 配置文件

4. Auto-configuration

Spring Boot尝试基于添加的依赖自动的配置Spring应用。例如,如果classpath下有一个HSQLDB,就不需要手动配置数据库连接的bean,Spring Boot会自动配置一个内存中的数据库(in-memory database)。
为了能够让Spring Boot 自动配置,需要在其中一个配置类(带有@Configuration注解的类)上添加@EnableAutoConfiguration 或者 @SpringBootApplication 注解

TIP:只能添加一个 @SpringBootApplication 或者 @EnableAutoConfiguration 注解,推荐只添加一个在主配置类上

4.1. Gradually Replacing Auto-configuration(逐步替换自动配置)

自动配置是非侵入式的,在任意的点上,都可以用自定义配置取代自动配置的某一具体部分,例如,如果你添加了自己的 DataSource Bean,默认嵌入的数据库支持就会作为备份使用
如果需要查看自动配置已经应用了哪些,选择 debug启动应用,这样会打印日志到控制台
(Doing so enables debug logs for a selection of core loggers and logs a conditions report to the console.)

4.2. Disabling Specific Auto-configuration Classes(禁用某个具体的自动配置)

如果你不想应用某个具体的自动配置,可以在 @SpringBootApplication 注解里面添加 exclude属性来禁用,示例如下

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication {
}

如果需要禁用的类不在classpath,可以使用 @SpringBootApplication 注解的属性 excludeName ,用全类名来定位,如果用的是 @EnableAutoConfiguration 而不是 @SpringBootApplication,也是可以使用 exclude 和 excludeName 这两个属性的。也可以使用 spring.autoconfigure.exclude 属性
TIP:
虽然自动配置类是 public,但是只是能够通过API的类名来禁用自动配置,类内部的内容比如嵌套的配置类或者是bean内部的方法只能是内部使用,不推荐直接使用

5. Spring Beans and Dependency Injection

一般使用 @ComponentScan 来扫描bean,使用 @Autowired 做构造注入
如果把代码放在 应用的root package下面,可以添加@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;
    }

    // ...

}

注:DatabaseAccountService 加了@Service注解,就是本身是一个 Service bean,然后里面通过构造注入的方式(@Autowired 加在了构造函数上)注入了一个RiskAssessor bean
如果一个bean有一个构造函数,也可以省略 @Autowired注解:

@Service
public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

Note:请注意,使用构造函数注入可以将riskAssessor字段标记为final,表示它不能随后更改。

6. Using the @SpringBootApplication Annotation

一个单独的@SpringBootApplication注解,使用之后具有以下三个特性
@EnableAutoConfiguration 开启springboot的自动配置
@ComponentScan 扫描位于主包下面的组件
@Configuration 允许注册额外的bean,或者注入额外的配置类

package com.example.myapplication;

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注解,相当于三个注解(@Configuration @EnableAutoConfiguration @ComponentScan)的作用之和

TIP:@SpringBootApplication注解提供别名可以定制 @EnableAutoConfiguration 和@ComponentScan 的属性

TIP:没有一个注解的特性是强制性的,可以选择替换任意一个注解已经开启的特性,比如:如果不想使用组件扫描或者配置属性扫描,可以像下面这样做
(就是说可以通过某中组合,来避免使用某个注解自带的某个功能)

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);
    }

}

在本例中,Application与任何其他Spring Boot应用程序一样,只是@Component annotated classes和@ConfigurationProperties annotated classes不会自动检测,并且用户定义的bean会显式导入(请参见@Import)。

7. Running Your Application

7.1. Running from an IDE

如果偶然间运行了web应用两次,会出现 “Port already in use” 的错误,选择 此时应选择 rerun 而不是 run,来保证已经运行 的实例先被关闭

7.2. Running as a Packaged Application

如果使用spring boot 的maven插件 生成了一个可执行的jar,可以使用java -jar命令 运行应用
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar

注:打开cmd,进入对应的目录,执行命令
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
即可
也可以通过debug的方式启动应用
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \

-jar target/myapplication-0.0.1-SNAPSHOT.jar

7.3. Using the Maven Plugin

SpringBoot maven 插件也含有一个run命令,可以快速的运行应用,$ mvn spring-boot:run
可以通过maven选项控制系统的环境变量
$ export MAVEN_OPTS=-Xmx1024m

7.4. Using the Gradle Plugin

7.5. Hot Swapping(热插拔)

JVM热插拔,在某种程度上受到字节码的限制,spring-boot-devtools也提供了快速重启应用的支持
详情查阅 Hot swapping “How-to”

8. Developer Tools

引入的方式
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")
}

NOTE:
打包好的应用默认是禁止这个 Developer tools 的,或者是以 java -jar 形式启动的应用,会默认是生产环境的应用,禁止这个Developer tools ,如果有必要使用Developer tools ,需要配置 -Dspring.devtools.restart.enabled=false

如果想使用远程的 devtools,需要禁用 excludeDevtools

8.1. Property Defaults

一些springboot支持的库使用缓存来改善性能,例如 模板引擎缓存通过编译模板来避免重复的编译模板文件,SpringMVC 可以添加HTTP缓存头文件,来快速的响应服务器请求的一些静态资源。
虽然缓存在生产环境的益处很大,但是在开发的时候会有适得其反的作用,会导致看不到最新的修改的东西,所以,spring-boot-devtools默认禁止了缓存
缓存选项的设置通常是在 application.properties文件中的,例如,Thymeleaf 提供的 spring.thymeleaf.cache 参数。spring-boot-devtools 在开发期间智能的应用了这些参数
因为开发Spring MVC and Spring WebFlux 应用的时候需要更多的web request 信息,需要为web logging group开启DEBUG 日志,可以看到关于请求的更多的信息,如:处理请求的 handler,response。如果需要看到更过的细节,可以配置
spring.http.log-request-details 这个配置
TIP:如果不行使用 上面的配置,可以选择 在application.properties配置 spring.devtools.add-properties 为 false
查看devtools 已经应用的参数列表 DevToolsPropertyDefaultsPostProcessor.

8.2. Automatic Restart

使用了spring-boot-devtools 之后,当classpath下面的文件发生改变时,应用就好自动的重启,这是一个很有用的特性,它提供了快速的针对于代码改变的反馈,默认情况下,static 和templates 的改变,不会重启。
触发重启
因为devtools 镜像了classpath下的资源,所以触发重启的唯一方式就是改变classpath下面的文件,在idea中,编译项目就可以触发
TIP:开发工具重启依赖于 关闭的钩子(the shutdown hook),如果禁用了 shutdown hook,重启就不会正确的启动 (SpringApplication.setRegisterShutdownHook(false)

当判断是否触发重启的时候,devtools会忽略名称是以下项目的变化: spring-boot, spring-boot-devtools, spring-boot-autoconfigure, spring-boot-actuator, and spring-boot-starter.

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

Restart vs Reload

重新启动用到了SpringBoot的两个类加载器,没有变化的类,(例如一些第三方的jar)会被加载到 一个基本加载器( base classloader)中,改变的类会被加载到 重启加载器( the restart classloade)中,重启加载器会被抛弃,并产生一个新的。这个方式表明应用重启会比冷启动(cold starts”)快,因为基本的类加载器没有变化,是可用,可迁移的
当重启没有那么快时,可以使用别的重新加载的技术 如 JRebel ,它是通过重新覆盖 类来实现的,这样更容易控制

8.2.1. Logging changes in condition evaluation

每次重启的时候,都会产生一个记录当前环境的评估报告,显示关于应用的 变化,如自动配置的变化,加载的bean 的变化,配置的参数的变化
禁用的方式:spring.devtools.restart.log-condition-evaluation-delta=false

8.2.2. Excluding Resources

指定某些资源变化的时候,不触发重启,例如:Thymeleaf templates。默认情况下:/META-INF/maven, /META-INF/resources, /resources, /static, /public, or /templates 下面的资源的变化不会触发重启,但是会触发实时重新加载( live reload)如果需要自定义这些位置,可以使用 spring.devtools.restart.exclude 参数。例如:只排除 /static and /public

spring.devtools.restart.exclude=static/,public/

如果需要保持默认的设置,添加额外的设置,使用 spring.devtools.restart.additional-exclude

8.2.3. Watching Additional Paths

如果需要不在classpath 下面的文件的变化也触发 重启,使用 spring.devtools.restart.additional-paths 来指定检测额外的路径。 可以使用 spring.devtools.restart.exclude 参数 额外路径下的触发的是 一个完全的重启还是一个 live reload

8.2.4. Disabling Restart

如果不想使用重启的特性,可以使用 spring.devtools.restart.enabled 属性来禁用,通常这一项可以在application.properties 里面配置(这样配置仍然会初始化重启的加载器,但是不会检测变化,也就无法重启)
如果需要完全的禁用重启(例如,和某个具体的库不兼容),可以设置 spring.devtools.restart.enabled System 值为false 在调用 SpringApplication.run(…) 之前,示例如下

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 filer ,只有这个文件改变的时候,才会触发重启
TIP:那个指定的文件的任何变化都会触发重启,但是重启只会发生在 devtools 确实检测到了变化的时候。
为了使用一个触发文件,需要设置 spring.devtools.restart.trigger-file 来指定文件的路径,这个文件必须要在classpath下面
示例的文件结构

src
± main
± resources
± .reloadtrigger
按照上面的文件结构,对应的配置是
spring.devtools.restart.trigger-file=.reloadtrigger
配置之后,只有在 src/main/resources/.reloadtrigger 文件变化的时候才会重启
可以指定spring.devtools.restart.trigger-file 是一个全局的文件,这样所有的项目就会同步的变化

8.2.6. Customizing the Restart Classloader

自定义重启的类加载器
默认情况下,每一个project 都会带有一个 重启加载器,通常的一些jar文件会用 基本的加载器加载,但是如果是多 module ( multi-module)的项目,不是每一个 module都被加载到项目中,此时需要一些自定义配置。一般来说:创建一个META-INF/spring-devtools.properties 文件
这个文件包含一些 前缀是 restart.exclude and restart.include 的配置。include 元素就是需要装进 重启加载器的项,exclude 是需要装进基本加载器的,属性的值是指定classpath的正则表达式:
restart.exclude.companycommonlibs=/mycorp-common-[\w\d-.]+.jar
restart.include.projectcommon=/mycorp-myproj-[\w\d-.]+.jar

每一个restart.include. or restart.exclude 开头的属性的键必须是唯一的

8.2.7. Known Limitations

重启这个特性和 ObjectInputStream 结合的不好,如果需要知道冲突的详情,需要使用 ConfigurableObjectInputStream和Thread.currentThread().getContextClassLoader().联合查看,一些第三方的库没有考虑这个情况,需要联系这个第三方库的作者

8.3. LiveReload

spring-boot-devtools 模块包含一个嵌入的 LiveReload server,在资源发生改变的时候可以触发浏览器的刷新,支持 Chrome, Firefox and Safari
如果不想启动这个 LiveReload server 可以使用配置 spring.devtools.livereload.enabled为 false
一次只能启动一个 LiveReload server,如果启动了多个应用,只有第一个应用会有 LiveReload server

8.4. Global Settings

如果需要配置 devtools 的全局参数
可以在 $HOME/.config/spring-boot 路径下使用下面的三种中的一个文件进行配置
spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml
例如,为了配置重启的触发文件 可以在对应的文件添加如下配置
文件路径:
~/.config/spring-boot/spring-boot-devtools.properties
配置项
spring.devtools.restart.trigger-file=.reloadtrigger

8.5. Remote Applications

在开发远程应用的时候,需要确定网络环境是安全的,否则不可以使用 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 这个参数

8.5.1. Running the Remote Client Application

8.5.2. Remote Update

8.5.3. Configuring File System Watcher

9. Packaging Your Application for Production

发布了52 篇原创文章 · 获赞 11 · 访问量 2451

猜你喜欢

转载自blog.csdn.net/weixin_41705396/article/details/105600414