其实我接触 Spring Boot 的时间并不长,因此还算一个初学者,这篇文章也算是我对 Spring Boot 学习以及使用过程当中的复盘,若是文章出现描述错误或表达不清晰的地方,欢迎你们在评论区留言互动。php
没想到 Spring Boot 这两年居然普及的这么快, 两年前刚毕业的时候,由于待的是二线城市的小公司,公司的技术栈并不追求新颖,而是追求稳定、能用就行的理念,因此项目上就一直使用传统的 SSM、SSH。java
当搭建后端框架时,须要手动添加 Maven 配置、各类 XML 配置,反正就是一个项目建立就要配置一遍,从我两年前写的这篇 SSM框架搭建,就能够看出该过程是有多么的繁琐,甚至有时候由于配置错误以至于一上午就又能够愉快的划水了...mysql
而项目部署时也是头大,首先须要安装 Tomcat,而后将项目编译打包成 war 包,再将 war 包放在 Tomcat 的 webapp 目录下部署运行,这个过程就以为很不方便...web
汇总一下构建一个传统项目须要的步骤:面试
由于如上种种问题,当一接触到 Spring Boot 后就被它简单的操做吸引了...redis
真羡慕如今的小伙伴,一上来就是用的 Spring Boot 了~ 不用再像我那会同样。spring
Spring Boot 的出现大大简化了传统 Web 框架的搭建过程,提升了开发效率,Spring Boot 总结后有如下几个特色:sql
这几个特色基本上也是面试 Spring Boot 时常问的,也正是由于这几个特色让以前繁琐的搭建过程变的简单。数据库
咱们都知道,特色并非解决问题的关键,因此咱们要了解,Spring Boot 究竟是如何解决问题的。apache
以前咱们使用 XML 方式时,有至关大的部分就是对 Bean 进行初始化并配置,好比下面这一段就是配置数据库链接信息:
<!-- 配置 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://10.211.55.4:3306/test" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
而使用 Spring Boot 后,会根据某些约定的规则对全部配置的 Bean 进行初始化,也就是约定优于配置,而后有的小伙伴就会问,那么什么是约定优于配置呢?
约定优于配置能够这样理解:
举例说明:
不符合规定的部分:例如,若是模型中有个名为 User 的类,那么数据库中对应的表就会默认命名为 user。只有在偏离这一约定时,例如将该表命名为 “user_info”,才需写有关这个名字的配置。
规定默认配置的地方:
是否对这个 yml 或者 properties 文件中配置了信息就实现了配置有点好奇?
咱们仍是以数据库链接信息为例:在 Spring Boot 中有一个 DataSourceAutoConfiguration 配置类,这个类会自动查找 application.yml 或者 properties 文件里的 spring.datasource.* 路径,而后相关属性会自动配置到数据源中。这个过程就属于约定大于配置,若是感兴趣的小伙伴能够进入这个类看看。
Spring Boot 应用程序能够不用部署到外部容器中,好比 Tomcat。Spring Boot 应用能够直接经过 Maven 命令将项目编译成可执行的 jar 包,经过 java -jar 命令启动便可,很是方便。
怎么不须要 Servlet 容器就启动起来了呢?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
只要加上这个依赖,Spring Boot 就帮咱们默认内嵌了 Tomcat,固然一样也支持修改,好比可使用 jetty(见标签7修改默认内置的Tomcat容器)。
内嵌就内嵌了吧,简单看一下 Tomcat 在 Spring Boot 中是如何启动的。`
应用监控是项目部署中必不可少的环节,之前咱们怎么知道系统实际运行的状况呢?
须要咱们人为的进行运维监控,好比对 cpu、内存、数据库链接等监控。若是是对系统接口,那么可能会单独写个测试接口来判断当前应用的健康程度,固然,大部分状况接口只要返回200就认为当前应用是健康的。
可是这种状况会存在很大的问题,首先前者会浪费人力资源,后者则由于固定接口形式没法真正意义上判断应用的健康状态。
而 Spring Boot 中提供了一个用于监控和管理自身应用信息的模块—Actuator,经过 Actuator,能够实现对程序内部运行状况进行监控,好比 Bean 加载状况、环境变量、日志信息、线程信息等。固然也能够自定义跟业务相关的监控,经过 Actuator 的端点信息进行暴露。这个有点 DevOps 的意思。
如何集成到 Spring Boot 中呢?
只须要在 pom.xml 中添加以下依赖便可:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
应用启动则直接能够访问:
application配置文件中可配置的参数:
management:
endpoints:
web:
# actuator的访问路径,替换默认/actuator
base-path: /monitor
# 设置是否暴露端点 默认只有health和info可见
exposure:
# include: env # 方式1: 暴露端点env,配置多个以,隔开
include: "*" # 方式2: 包括全部端点,注意须要添加引号
# 排除端点,若是不排除则只须要访问该应用的/shutdown 端点就能实现关闭该应用的远程操做
exclude: shutdown
server:
port: 8888 #新开监控端口,不和应用用同一个端口,
endpoint:
health:
show-details: always # 显示db、redis、rabbti链接状况等
shutdown:
enabled: true #默认状况下,除shutdown之外的全部端点均已启用。手动开启
按照如上配置则访问路径为:http://localhost:8888/monitor
咱们能够看到有不少节点(图中省略),这些结点被称做 端点,以下是这些端点的描述:
ID | 描述 | 默认启用 | 默认公开 |
---|---|---|---|
auditevents |
公开当前应用程序的审计事件信息 | Yes | No |
beans |
显示应用程序中全部Spring bean的完整列表 | Yes | No |
conditions |
显示在配置和自动配置类上评估的条件以及它们是否匹配的缘由 | Yes | No |
configprops |
显示全部@ConfigurationProperties 对照的列表 |
Yes | No |
env |
从Spring的ConfigurableEnvironment 中公开属性 |
Yes | No |
flyway |
显示已应用的任何Flyway数据库迁移 | Yes | No |
health |
显示应用程序健康信息 | Yes | Yes |
httptrace |
显示HTTP跟踪信息(默认状况下,最后100个HTTP请求-响应交互) | Yes | No |
info |
显示任意应用程序信息 | Yes | Yes |
loggers |
显示和修改应用程序中记录器的配置 | Yes | No |
liquibase |
显示已应用的任何Liquibase数据库迁移 | Yes | No |
metrics |
显示当前应用程序的“指标”信息 | Yes | No |
mappings |
显示全部@RequestMapping 路径对照的列表 |
Yes | No |
scheduledtasks |
显示应用程序中调度的任务 | Yes | No |
sessions |
容许从Spring Session支持的会话存储中检索和删除用户会话 | Yes | No |
shutdown |
让应用程序优雅地关闭 | No | No |
threaddump |
执行线程转储 | Yes | No |
如上所知,若是想显示应用程序健康信息,那么就访问 health 端点,即:
http://127.0.0.1:8888/monitor/health
其余的你们能够自行尝试看一下,额外须要注意的是 shutdown 端点,项目中必定要排除,不然只须要访问该应用的 /shutdown 端点就能实现该应用的远程关闭操做,十分危险。
这就完了?
显然不是,上边这样直接访问端点,而后返回 JSON 数据,显然很不直观,毕竟如今很流行可视化嘛~ 咳咳。
因此这时候咱们能够经过 Spring Boot Admin 来对 actuator 返回的这些数据进行整理。
关于 Spring Boot Admin 的介绍:
Spring Boot Admin 是用于管理和监控 Spring Boot 应用程序运行状态的。在 Spring Boot 项目中能够经过集成 Spring Boot Admin Client 向 Spring Boot Admin Server 进行注册(经过 HTTP),这样咱们就能够在 Spring Boot Admin Server 统一管理 Spring Boot 应用。可视化是端点之上的 Vue 项目。
提供功能以下:
使用 Spring Boot Admin 也是很是的简单,直接添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>2.3.0</version>
</dependency>
配置文件以下:
spring:
boot:
admin:
# 修改上下文路径
context-path: /admin
client:
url: http://127.0.0.1:${server.port}/admin
再在启动类上加上 @EnableAdminServer 注解,齐活,完事。
经过如上界面,咱们能够清楚的看到应用的名称和 IP 端口信息,应用名称是默认的,也能够在配置文件中经过 spring.application.name 来自定义名称。
咱们还能够点击服务信息进去查看详情,左边是对应的功能菜单,右边是数据展现的页面。详情中有健康信息、线程信息、JVM 内存等信息,都经过图形的方式展现,一目了然。
经过左侧功能菜单能够看到还有 日志、JVM、缓存 等管理功能,你们能够点点看看。
关于 Spring Boot Starter 相信你们必定不陌生,不少第三方工具的引入都是涉及到 Starter 包,Starter 包能够说是 Spring Boot 中的核心功能,Starter 的出现,简化了 Spring 不少工做。不懂就问环节:什么是 Starter?`
总之,Starter 包简化框架集成难度,将 Bean 的自动装配逻辑封装在 Starter 包内部,同时也简化了 Maven Jar 包的依赖,对框架的集成只须要加入一个 Starter 包的配置,下降了烦琐配置的出错概率。
以下是 Spring Boot 提供的开箱即用 Starter 包:
starter | desc |
---|---|
spring-boot-starter-web |
用于快速构建Web,包含 RESTful 风格框架、SpringMVC和默认的嵌入式容器Tomcat |
spring-boot-starter-test |
用于测试 |
spring-boot-starter-data-jpa |
带有Hibermate的Spring Data JPA,用于操做数据库。 |
spring-boot-starter-jdbc |
传统的JDBC支持 |
spring-boot-starter-thymeleaf |
支持Thymeleaf模板 |
spring-boot-starter-mail |
支持Java Mail、Spring Email 发送邮件 |
spring-boot-starter-integration |
Spring框架建立的一个API,面向企业应用集成(EAI) |
spring-boot-starter-mobile |
SpringMVC的扩展,用来简化手机上的Web应用程序开发 |
spring-boot-starter-data-redis |
快速整合并操做 Redis:经过Spring Data Redis、Redis Client使用Redis |
spring-boot-starter-validation |
Bean Validation是一个数据验证的规范,Hibernate Validator是一个数据验证框架 |
spring-boot-starter-websocket |
相对于非持久的协议HTTP,Websocket 是一个持久化的协议 |
spring-boot-starter-web-services |
SOAP Web Services |
spring-boot-starter-hateoas |
为服务添加HATEOAS功能 |
spring-boot-starter-security |
用Spring Security进行身份验证和受权 |
spring-boot-starter-data-rest |
用Spring Data REST公布简单的REST服务 |
建立 Spring Boot 有两种方式:
工具环境 IDEA,下文是基于 Spring Initializr 脚手架建立。
经过 IDEA 建立 Spring Boot 项目实在是太简单了:
关于下一步以后,无非就是选择建立项目的方式(Maven/Gradle),Spring Boot 版本(2.2.2.RELEASE),引入的依赖(Web/SQL/NoSQL/Security等),在这就不赘述了。
Spring Boot 项目打包无非就 「打 jar 包、打 war 包」 这两种状况,这二者的应用场景不一样,各有优缺点。
jar 包部署优势:
jar 包部署缺点:
war 包部署优势:
war 包部署缺点:
至于最终选择哪一个,本文不追究,毕竟都是要根据实际项目来讲的。
以打 jar 包为例:
首先须要在 pom.xml 文件中配置 spring-boot-maven-plugin 打包插件,也就是咱们一般看到的:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
这样就能够在 Tmerinal 控制台经过 maven 命令进行打包了:mvn package
或者是能够直接在 IDEA 右侧的 Maven 标签:
有小伙伴可能好奇,难道不须要设置 <packaging>jar</packaging>
吗?
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<packaging>jar</packaging>
...
</project>
其实默认的 就是 jar 方式。
一般在实际开发中,每每涉及到好几个环境,好比开发环境、本地环境、测试环境等等,一般不一样环境下的配置信息是不同的「好比端口号?数据库链接信息等」,由于咱们每次只能使用一个配置环境,若是频繁的修改配置以达到效果,天然是麻烦的不行,且很容易出错。
而在 Spring Boot 中,咱们能够经过 spring.profiles.active 来激活对应的配置文件。
好比建立以下三个文件:
application.yml「主文件」
咱们想要使用 dev 开发环境,只须要在 application.yml 中使用 spring.profiles.active=dev 就能够完成指定:
spring:
profiles:
active: dev
尽管Spring Boot内置了 Tomcat ,可是在高并发场景下的 Tomcat 相对来讲比较弱。好比在相同的机器配置下,模拟相等的请求数,Undertow在性能和内存使用方面都是最优的。而且Undertow新版本默认使用持久链接,这将会进一步提升它的并发吞吐能力。因此,若是是高并发的业务系统,Undertow 是最佳选择。
问题是怎么替换?
由于 spring-boot-starter-web 中默认自带的容器是 Tomcat,若是想要替换成 Undertow 也是很是简单的。
首先须要排除 spring-boot-starter-web 包中的 Tomcat,而后单独增长 undertow 容器的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除Tomcat依赖 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加 Undertow依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
之前读取 spring 的配置文件,都是经过工具类类读取,其实无非就是读取 xml 文件,好比,经过 ClassPathXmlApplicationContext 加载到文件,而后再经过 上下文拿到 对应的Bean,再取参等。
而在 Spring Boot 中读取配置文件有三种方式:
Environment
@Value
@ConfigurationProperties
咱们一一看看这三种方式:
application.yml 中的模拟数据:
niceyoo:
name: 张三
age: 24
Environment 用于管理当前的应用环境信息,定义了获取 Profile 的方法,同时继承了 PropertyResolver,PropertyResolver 提供了属性访问的相关方法。
也就是咱们可使用 Environment 的 getProperty() 方法读取指定配置 Key 的内容。
代码中体现:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private Environment environment;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
String name = environment.getProperty("niceyoo.name");
Integer age = Integer.valueOf(environment.getProperty("niceyoo.age"));
System.out.println(name+" " +age);
}
}
@Value 方式就简单多了,直接在接收的属性上加上该注解便可:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Value("niceyoo.name")
private String name;
@Value("niceyoo.age")
private Integer age;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
System.out.println(name+" " +age);
}
}
使用该注解能够直接注入到实体类中,方便值的同一管理。
好比咱们建立一个 Model 实体类,定义 name、age 属性,而后实现 get\set 方法,再在实体类上加上 @Configuration 和 @ConfigurationProperties(prefix="niceyoo") 注解,并指定前缀为 niceyoo。
@Configuration
@ConfigurationProperties(prefix="niceyoo")
public class Model {
private String name;
private Integer age;
省略get、set方法
}
这样就能够将 niceyoo 下面的值直接对应到实体上了,其中加入 @Configuration 注解,咱们在使用时能够直接经过 @Autowired 进行注入。
取值代码:
@Controller
@RequestMapping(value = "/test")
public class TestController {
@Autowired
private Model model;
@PostMapping("/test")
@ResponseBody
public void test(@RequestBody User user) {
System.out.println(model.getName()+" " +model.getAge());
}
}
之前 Spring 主打轻量级应用框架,但随着外界不断地进行扩充,像是 Shiro、Security、MQ、Redis、ElasticSearch 等等等等, 总之就是 Spring 几乎能够作任何事了,可是相应的问题也来了。
Spring 每集成一个第三方软件,就须要手动增长一些配置,随着新软件的加入,以致于须要引入愈来愈多的配置,且这些配置各玩各的,难以理解,难以管理,我记得我实习时的那家公司就是这样,各类五花八门的配置文件,以致于常常配置出错,而后解决配置相关的问题就须要很久。
工欲善其行,必先利其器。
Spring Boot 的出现能够说真正的颠覆了之前传统的 Web 项目,开发人员不再用配置繁琐的 xml 文件了,简直是解放了双手,整个项目的配置文件也变得简洁了。
正所谓简洁并不意味着简单,Spring Boot 只是将众多复杂的功能进行了封装,让咱们在使用的时候足够的简单。
关于 Spring Boot 的知识点能够说太多太多了,文中只是把本身能想到的几点描述了出来。`