Spring Boot是微服务架构的基础。相比以前的Spring,它主要是省去了大量的样板式配置,取而代之的是根据条件的自动化配置,也提升了开发体验和增加一些新的特性,使开发人员把更多的精力放到业务代码上。所以,对于Spring Boot的学习主要是了解Spring Boot的开发方式,深入一点,就是了解其内部的自动配置等特性。
起步
Spring Boot的初始项目可以通过三种方式来创建。
- 通过start.spring.io 来可视化创建项目,填写项目构建方式(Maven/Gradle)以及项目相关信息和项目包含的模块,下载到本地后直接用IDE打开即可。
- 下载专用IDESpring Tool Suite ,点击File->new->Spring Start Project即可进入新建Spring Boot项目流程。
- 通过Spring Boot CLI 命令行工具来构建项目,此种方式需要用到Groovy语言。此方式本文暂不讨论。
除了Spring Boot CLI通过写少量Groovy脚本即可通过CLI来自动推断需要哪些包并自动引入和配置外,其它两种方式都需要手动来选择或配置项目所需模块。以如图:
在上面的列表中,可以根据我们所需来自由选择依赖项,例如,如果是web开发,需要勾选web就可以;如果需要数据持久化,可以勾选JPA或MyBatis等。在尝试用Spring Boot做web开发的初始阶段,建议选择web(SpringMvc),JPA/Mybatis(持久化),H2(嵌入式数据库),thymeleaf(模板引擎)。创建完成项目后若是Maven构建方式,打开Pom.xml文件就会发现,这一整套能够开发出简单应用的项目所需的依赖非常少,只有我们所选择的依赖项,并且没有了那么多的配置文件,只有一个application.properties配置文件。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
这就体现出Spring Boot的两个好处:自动配置,起步依赖。
- 自动配置:所有的配置都不是在配置文件中显示声明,而是根据项目中是否有某个包的依赖在代码中自动完成配置,如果没有则忽略。Spring Boot所支持的自动配置依赖列表在
spring-boot-autoconfiger.jar
包中查看,在项目中如果遇到Spring Boot没有实现的第三方依赖自动配置,可以参照其中的代码来自定义实现。也可以扩展其已有的配置类,重写其中的configure方法来覆盖默认的自动配置。 - 起步依赖:Spring Boot通过提供起步依赖降低项目依赖的复杂度。起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其它库的传递依赖,使这些库加在一起支持某项功能。起步依赖一般都会以
spring-boot-start-
开头。例如web的起步依赖是spring-boot-start-web
其传递依赖有org.springframework:spring-web,org.springframework:spring-webmvc,com.fasterxml.jackson.core:jackson-databind
等依赖项。其中各个依赖项的版本都是经过Spring Boot测试的没有兼容问题的版本。然而在实际开发中会有某些情况需要自己来控制某个传递依赖的版本,比如上面com.fasterxml.jackson.core:jackson-databind
修复了某个bug的版本,这种情况在Pom.xml中可以通过添加指定版本号的该依赖项的形式来覆盖默认的传递依赖引用:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>3.2.1</version>
</dependency>
至此,一个简单Spring Boot项目已经完成,我们可以像以往一样直接开始写业务代码,如创建实体类,写Controller,添加视图等等。在写完代码后,Spring Boot的运行方式有两种:
- 直接在IDE中debug(本人用的是Spring Tool Suite,运行方式是项目->DebugAs->Spring Boot App)。也可以在Pom.xml中把jar改成war,在tomcat中运行。
- 执行maven install操作,会在项目根目录的target文件夹内生成demo.jar可执行程序,通过
java -jar demo.jar
运行即可
以上两种方式运行后可以在浏览器中输入localhost:8080
来访问你的web程序。
通过属性文件(application.properties)外置配置
Spring Boot自动配置的Bean提供了300多个用于微调的属性。当调整设置时,只需要在环境变量、java系统属性、命令行参数或属性文件里进行指定就可以了。其中,属性文件有两种文件格式,一种就是我们看见的默认的application.properties
,一种是application.yml
。
以配置服务启动的端口为例,两种配置文件的格式分别为(server.port设置为0的作用是在启动时会选择一个可用的随机端口,这样能避免端口冲突):
application.properties
server.port=0
application.yml
server:
port:0
同时,也可以像以前一样将应用程序所需的自定义配置写到属性配置文件中,而且更方便。例如,我们要把项目名称等相关信息写到配置文件中可以这样写
project.Name='新项目'
project.Company='***公司'
然后,在项目中写一个对应的Bean,Bean加上@ConfigurationProperties("project")
注解,就可以实现将带有project前缀的配置加载到对应属性中,代码如下:
@Component
@ConfigurationProperties("project")
public class ProjectProperties{
private String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
………………………………
}
这样,在所需要的地方可以直接注入这个Bean来方便使用配置中的属性了。
Spring Boot的属性配置文件也可以通过Spring.profiles.active属性来激活指定的配置文件,以实现在不同环境使用不同配置文件,如果使用application.properties
属性文件,则额外配置文件的命名规则为application-{profile}.properties
。例如,设置Spring.profiles.active=product,则额外配置文件名字为application-product.properties
,这样在程序运行时会自动读取application-product.properties
文件的配置属性。Profile在Spring3.1版本就已经有,但是在Spring Boot中使用更为方便。
Actuator
Actuator提供很多生产级特性,比如监控和度量Spring Boot应用。使用方法就是直接添加起步依赖 spring-boot-starter-actuator
或在创建项目时勾选Actuator。Actuator暴露的接口可以提供很多Spring Boot各种信息以及运行状态、所使用资源以及空闲资源等,也可以用来控制Spring Boot应用关闭等操作。也可以通过它来查看Spring Boot所做的自动配置信息。
比如,在Spring Boot运行时,通过浏览器访问localhost:8080/health
就会得到应用是否运行的状态:
{"status":"UP"}
输入localhost:8080/metrics
就会得到各种应用程序度量信息,比如内存用量和HTTP请求次数等:
{
"mem": 330481,
"mem.free": 103166,
"processors": 8,
"instance.uptime": 4087,
"uptime": 7873,
"systemload.average": -1.0,
"heap.committed": 268800,
"heap.init": 131072,
"heap.used": 165633,
"heap": 1849856,
"nonheap.committed": 62720,
"nonheap.init": 2496,
"nonheap.used": 61683,
"nonheap": 0,
"threads.peak": 28,
"threads.daemon": 26,
"threads.totalStarted": 32,
"threads": 28,
"classes": 8913,
"classes.loaded": 8913,
"classes.unloaded": 0,
"gc.ps_scavenge.count": 9,
"gc.ps_scavenge.time": 61,
"gc.ps_marksweep.count": 2,
"gc.ps_marksweep.time": 96,
"httpsessions.max": -1,
"httpsessions.active": 0,
"datasource.primary.active": 0,
"datasource.primary.usage": 0.0
}
所有的结果都是以json形式返回。下面时暴露的接口列表:
HTTP方法 | 路径 | 描述 |
---|---|---|
GET | /autoconfig | 提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过 |
GET | /configprops | 描述配置属性(包含默认值)如何注入Bean |
GET | /beans | 描述应用程序上下文里全部Bean,以及它们的关系型 |
GET | /dump | 获取线程活动的快照 |
GET | /env | 获取全部环境属性 |
GET | /env/{name} | 根据名称获取特定的环境属性 |
GET | /health | 报告应用程序的健康指标 |
GET | /info | 获取应用程序的定制信息,这些信息由info打头的属性提供 |
GET | /mappings | 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系 |
GET | /metrics | 报告各种应用程序度量信息 ,比如内存用量和HTTP请求次数等 |
GET | /metrics/{name} | 报告指定名称应用程序度量值 |
GET | /shutdown | 关闭应用程序,要求endpoints.shutdown.enable设置为true |
GET | /trace | 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等),只保存前100条请求信息,也可以通过配置来实现持久化到数据库 |