Spring Boot

相关链接

Spring Boot文档

快速构建Spring boot项目的网站

《Spring Boot+Vue全栈开发实战》王松

环境要求

  • Java 8或9
  • Spring Framework 5.0.8.RELEASE或更高版本
  • 构建工具的版本要求为Maven 3.2+或Gradle 4

创建Maven工程

通过命令创建Maven工程

1
mvn archetype:generate -DgroupId=org.sang -DartifactId=chapter01 -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

-DgroupId 组织Id(项目包名)

-DartifactId ArtifactId(项目名称或者模块名称)

-DarchetypeArtifactId 项目骨架

-DinteractiveMode 是否使用交互模式

使用命令将项目创建好之后,直接用Eclipse或者IntelliJ IDEA打开即可

Eclipse中创建Maven工程

  1. File–New–Maven Project
  2. 选中Use default Workspace location复选框
  3. 选择项目骨架,保持默认设置即可
  4. 输入项目信息,点击Finish完成创建

IntelliJ IDEA创建Maven工程

  1. 创建项目时选择Maven,但可不必选择项目骨架,直接点Next按钮即可

    File–New–New Project–Maven

  2. 输入组织名称、模块名称、项目版本号等信息

  3. 选择项目位置,点击Finish,完成创建

项目构建

添加依赖

1
2
3
4
5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>

spring-boot-starter-parent是个特殊的Starter,提供了些Maven的默认配置,同时还提供了dependency-management,可使在引入其他依赖时不必输入版本号,方便依赖管理。

Spring Boot提供的Starter非常多,这些Starter主要为第三方库提供自动配置,例如开发个Web项目,需要引入Web的Starter:

1
2
3
4
5
6
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

编写启动类

1、java目录下创建项目的包,包里创建一个App类:

1
2
3
4
5
6
7
8
9
@EnableAutoConfiguration
@ComponentScan
public class App{
public static void main(String[] args){
//App.class:告诉Spring哪个是主要组件
//args:运行时输入的其他参数
SpringApplication.run(App.class, args);
}
}

@EnableAutoConfiguration 表示开启自动化配置。

由于项目中添加了spring-boot-starterweb依赖,因此开启了自动化配置之后会自动进行Spring和Spring MVC的配置

@ComponentScan 配置这个才会进行包扫描,会把控制器注册到Spring MVC容器中

也可以用 @SpringBootApplication来代替@EnableAutoConfiguration@ComponentScan

1
2
3
4
5
6
@SpringBootApplication
public class App{
public static void main(String[] args){
SpringApplication.run(App.class, args);
}
}

2、创建一个控制器

1
2
3
4
5
6
7
@RestController
public class HelloController{
@GetMapping("/hello")
public String hello(){
return "hello spring boot!";
}
}

启动Spring Boot

方式一:Maven命令启动

  1. 在命令行窗口下,切换到项目目录下

  2. mac:(mvnw/mvn)

    ./mvnw spring-boot:run(maven)、./gradlew bootRun(gradle)

    windows:(mvnw/mvn)

    mvnw spring-boot:run(maven)、gradlew bootRun(gradle)

方式二:直接运行main方法

方式三:打包启动

首先添加个plugin到pom.xml中

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>springframework-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

然后运行mvn命令进行打包

1
mvn package

打包完成会在项目的target下生成个jar文件,通过java -jar命令直接启动这个jar文件

如:

1
java -jar .\chapter01-1.0-SHAPSHOT.jar

Spring Boot的简便创建方式

在线创建

快速构建Spring boot项目的网站

使用IntelliJ IDEA创建

  1. New Project–Spring Initializr

  2. 输入项目基本信息(组织Id、模块名称、项目构建类型、最终生成包的类型、Java版本、开发语言、项目版本号、项目名称、项目描述、项目的包)

  3. 选择依赖

  4. 选择项目创建路径

使用STS创建

New–Spring Starter Project

其他同IntelliJ IDEA中基本一致

Spring Boot 基础配置

不使用 spring-boot-starter-parent

spring-boot-starter-parent主要提供了

  • Java版本默认使用1.8
  • 编码格式默认使用UTF-8
  • 提供Dependency Management进行项目依赖的版本管理
  • 默认的资源过滤与插件配置

使用spring-boot-starter-parent虽然方便,但开发微服务项目或者多模块时一般使用公司自己的parent,这是还想进行项目依赖版本的统一管理,就需要使用dependencyManagement来实现,就不用继承spring-boot-starter-parent了,但Java版本、编码格式等需要手动配置

1
2
3
4
5
6
7
8
9
10
11
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

自己配置Java版本(添加个plugin)

1
2
3
4
5
6
7
8
9
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.9</target>
</configuration>
</plugin>

自己配置编码格式(在pom.xml中加入如下配置)

1
2
3
4
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

@Spring BootApplication

@Spring BootApplication是加在项目的启动类上的。

@Spring BootApplication实际上是一个组合注解,定义如下:

1
2
3
4
5
6
7
8
9
@Spring BootApplication
@EnableAutoConfiguration
@ComponentScan(excludeFilters={
@Filter(type=FilterType.CUSTOM, classes=TypeExcludeFilter.class),
@Filter(type=FilterType.CUSTOM,classes=AutoConfigurationExcludeFilter.class)
})
public @interface Spring BootApplication{
//略
}

这个注解由三个注解组成

第一个:@Spring BootConfiguration的定义如下:

1
2
3
4
@Configuration
public @interface Spring BootConfiguration{

}

原来就是一个@Configuration,所以@Spring BootApplication的功能就是表明这是一个配置类,开发者可以在这个类中配置Bean。这个类所扮演的角色类似于Spring中的applicationContext.xml文件的角色

第二个:@EnableAutoConfiguration表示开启自动化配置。Spring Boot中的自动化配置是非侵入式的,在任意时刻都可以用自定义皮诶之替代自动化配置中的某一个配置。

第三个:@ComponentScan完成包扫描,是Spring中的功能。@ComponentScan默认扫描的是当前类所在包下的。因此建议把启动类放在根包中。

项目启动类中的@ComponentScan会扫描@Service@Repository@ComponentController@RestControllerConfiguration注解的类

虽然项目启动类包含@Configuration注解,但开发者可创建个新的类专门用来配置Bean,便于管理。这个类只需要加上@Configuration注解即可,如:

1
2
3
@Configuration
public class MyConfig{
}

定义banner

Spring Boot项目启动时会打印一个banner,这个banner可定制,在resources目录下创建个banner.txt,这个文本内容会在启动时打印出来。

若想讲TXT文本设置成艺术字体,有以下几个在线网站可供参考:

想关闭banner,可通过修改项目启动类的main方法:

1
2
3
4
public static void main(String[] args){
SpringApplicationBuilder builder = new SpringApplicationBuilder(Chapter012Application.class);
builder.bannerMode(Banner.Mode.OFF).run(args);
}

Web容器配置

Spring Boot可内置Tomcat、Jetty、Undertow、Netty等容器。当添加了spring-boot-starter-web依赖后,默认使用Tomcat作为Web容器。

Tomcat配置

如果需要对Tomcat做进一步配置,可在application.properties中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#Web容器的端口号
server.port=8081
#当项目出错时跳转去的页面
server.error.path=/error
#session失效的时间,30m表示30分钟,如果不写单位默认是秒。而Tomcat配置session过期时间单位是分钟,所以如果单位是秒的话,时间会转换为一个不超过所配置描述的最大分钟数,如配置119,默认单位秒,则实际session过期时间是1分钟
server.servlet.session.timeout=30m
#表示项目名称,不配置时默认为/。若配置了,要在访问路径中加上配置的路径
server.servlet.context-path=/chapter02
#表示Tomcat请求编码
server.tomcat.uri-encoding=utf-8
#表示Tomcat最大线程数
server.tomcat.max-threads=500
#存放Tomcat运行日志和临时文件的目录,若不配置默认使用系统的临时目录
server.tomcat.basedir=/home/sang/tmp

HTTPS配置

jdk中提供了个Java数字证书管理工具keytool,在/jdk/bin目录下。可通过此工具生成一个数字证书:(在cmd窗口输入)

1
keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore sang.p12 -validity 364

-genkey 表示要创建一个新的密钥

-alias 表示keystore的别名

-keyalg 表示使用的加密算法是RSA,一种非对称加密算法

-keysize 表示密钥的长度

-keystore 表示生成的密钥存放位置

-validity 表示密钥的有效时间,单位是天

会生成一个sang.p12的文件,此文件放到根目录下,再在application.properties中做如下配置

1
2
3
server.ssl.key-store=sang.p12
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=123456

key-store 表示密钥文件名

key-alias 表示密钥别名

key-store-password 即在cmd命令执行过程中输入的密码

配置成功后需要用 https 访问,Spring Boot 不支持同时在配置中启动HTTP和HTTPS。不过可以配置请求重定向(将HTTP重定向为HTTPS):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Configuration
public class TomcatConfig{
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(){
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context){
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
factory.addAdditionalTomcatConnectors(createTomcatConnector());
return factory;
}
private Connector createTomcatConnector(){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8081);
return connector;
}
}

将8080端口转发到8081上去

Jetty配置

在 Spring Boot 中嵌入 Jetty,配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
</dependency>

Undertow配置

Undertow是红帽公司开源的Java服务器,具有非常好的性能,配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependency>

Peoperties配置

Spring Boot采用了大量的自动化配置,但实际项目中有些需要手动配置,就得在resources目录下的application.properties中修改(也可以使用YAML配置来替代application.properties配置)

application.properties配置文件一共可出现在如下4个位置:

  • 项目根目录下的config文件夹中
  • 项目根目录下
  • classpath下的config文件夹中
  • classpath下

加在的优先级依次降低

如果用application.yml作为配置文件,配置文件的优先级与上面的一致。

默认名称是application.properties,若想改成自定义的名称,如 app.properties,在项目打包成jar包成功后,使用如下命令运行

1
java -jar chapter02-2-0.0.1-SHAPSHOT.jar --spring.config.name=app

在运行时再制定配置文件的名称。使用 spring.config.location key 指定配置文件所在目录(注意需要以“/”结束),代码如下:

1
java -jar chapter02-2-0.0.1-SHAPSHOT.jar --spring.config.name=app --spring.config.location=classpath:/

SpringBoot+Mybatis打印sql日志

application.properties中添加

1
2
#cn.monecity.mapper是 *Mapper.java 所在的包名
logging.level.cn.monecity.mapper=debug

类型安全配置属性

无论 Properties 配置还是 YAML 配置,最终都会被加载到 Spring Environment 中。Spring 提供了@Value 注解以及 EnvironmentAware 接口来将 Spring Environment 中的数据注入到属性上,Spring Boot 对此进一步提出了类型安全配置属性(Type-safe Configuration Properties),这样即使在数据量非常庞大的情况下,也可以更加方便地将配置文件中的数据注入 Bean 中。考虑在application.properties中添加如下一段配置:

1
2
3
book.name=三国演义
book.author=罗贯中
book.price=30

将这一段配置数据注入如下 Bean 中:

1
2
3
4
5
6
7
8
@Component
@ConfigurationProperties(prefix="book")
public class Book{
private String name;
private String author;
private Float price;
//省略 getter/setter
}

@ConfigurationProperties中prefix属性描述了要加载的配置文件的前缀

如果配置文件是个YAML文件,那么可以将数据注入一个集合中。

Spring Boot 采用了一种宽松的规则来进行属性绑定,如果Bean中的属性名位authorName,那么配置文件中的属性可以是book

.author_name、book.author-name、book.authorName或者book.AUTHORNAME

以上的配置可能会乱码,需要对中文进行转码:IntelliJ IDEA中 File--Settings--Editor--File Encodings选择全部的编码为UTF-8

最后创建BookController进行简单测试

1
2
3
4
5
6
7
8
9
@RestController
public class BookController{
@Autowired
Book book;
@GetMapping("/book")
public String book(){
return book.toString();
}
}

然后在浏览器中输入 localhost:8080/book来看是不是页面展示Book{name='三国演义',author='罗贯中',price=30.0}

YAML配置

YAML常规配置

YAML是JSON的超集,简介而强大,是一种专门用来书写配置文件的语言,可以替代application.properties。在创建一个Spring Boot项目时,引入的spring-boot-starter-web依赖间接地引入了snakeyaml依赖,snakeyaml会实现对YAML配置的解析。YAML的使用非常简单,利用缩进来表示层级关系,并且大小写敏感。在Spring Boot项目中使用YAML只需要在resources目录下创建一个application.yml文件即可,然后向application.yml中添加如下配置:

1
2
3
4
5
6
server:
port:80
servlet:
context-path:/chapter02
tomcat:
uri-encoding:utf-8

这段配置等效于application.properties中的

1
2
3
server.port=80
server.servlet.context-path=/chapter02
server.tomcat.uri-encoding=utf-8

此时就可以将resources目录下的application.properties删除,完全使用YAML完成文件的配置。

YAML复杂配置

如:

1
2
3
my:
name:江南一点雨
address:China

像Properties配置文件一样,这一段配置也可以注入一个Bean中,代码如下:

1
2
3
4
5
6
7
@Component
@ConfigurationProperties(prefix="my")
public Class User{
private String name;
private String address;
//省略 getter/setter
}

YAML还支持列表配置,例如:

1
2
3
4
5
6
7
my:
name:江南一点雨
address:China
favorites:
- 足球
- 徒步
- Coding

注入如下Bean中:

1
2
3
4
5
6
7
8
@Component
@ConfigurationProperties(prefix="my")
public class User{
private String name;
private String address;
private List<String> favorites;
//省略 getter/setter
}

还支持更复杂的配置,即集合中也可以是一个对象,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
my:
users:
- name: 江南一点雨
address: China
favorites:
- 足球
- 徒步
- Coding
- name: Sang
address: GZ
favorites:
- 阅读
- 吉他

这组配置在集合中放的是一个对象,一次可以注入如下集合中:

1
2
3
4
5
6
7
8
9
10
11
12
@Component
@ConfigurationProperties(prefix="my")
public class Users{
private List<User> users;
//省略 getter/setter
}
public class User{
private String name;
private String address;
private List<String> favorites;
//省略 getter/setter
}

YAML虽然方便,但也有缺陷,如无法使用@PropertySource注解加载YAML文件,如果项目中有这种需求,还是需要使用Properties格式的配置文件。

Profile

应用于频繁切换开发环境、测试环境、生产环境的场景。

Spring对此提供了解决方案(@Profile注解)

Spring Boot得更加简洁,Spring Boot约定的不同环境下配置文件名称规则为 application-{profile}.properties,profile占位符表示当前环境的名称,具体配置步骤如下:

  1. 创建配置文件

    在resources目录下创建两个配置文件:

    application-dev.properties(开发环境的配置)

    1
    server.port=8080

    application-prod.properties(生产环境的配置)

    1
    server.port=80
  2. 配置application.properties

    1
    spring.profiles.active=dev

    其中dev 表示application-dev.properties启动

    改成prod,表示application-prod.properties启动

  3. 在代码中配置

    对于第二步在application.properties中添加配置,也可以在代码中来完成。在启动类的main方法上添加如下代码:

    1
    2
    3
    SpringApplicationBuilder builder = new SpringApplicationBuilder(Chaper013Application.class);
    builder.application().setAdditionalProfiles("prod");
    builder.run(args);
  4. 项目启动时配置

    对于第2和第3步提到的两种配置方式,也可以在将项目打成jar包后启动时,在命令行动态指定当前环境,示例命令如:

    1
    java -jar chapter01-3-0.0.1-SHAPSHOT.jar --spring.profiles.active=prod

Spring Boot 整合视图层技术

官方推荐的模板引擎是Thymeleaf,但对于FreeMarker也支持。不推荐使用JSP技术。

Spring Boot 整合Web开发

笔记

注解

@SpringBootApplication

@EnableAutoConfiguration

@ComponentScan

@Filter

@MapperScan

@Component

@Autowired

@XxlJob

@Service

@Configuration

@EnableCaching

@Bean

@Resource

@Transactional