Spring Boot 介绍

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。Spring Boot 默认配置了很多框架的使用方式,就像 Maven 整合了所有的 Jar 包,Spring Boot 整合了所有的框架。它的核心设计思想是:约定优于配置,Spring Boot 所有开发细节都是依据此思想进行实现的。

Spring Boot 是一套全新的框架,它来自于 Spring 大家族,因此 Spring 所有具备的功能它都有并且更容易使用;同时还简化了基于 Spring 的应用开发,通过少量的代码就能创建一个独立的、产品级别的 Spring 应用。 

下图展示出了 Spring Boot 在 Spring 生态中的位置:

该项目主要的目的是:

  • 上手 Spring 开发更快、更广泛;
  • 使用默认方式实现快速开发;
  • 提供大多数项目所需的非功能特性,诸如:嵌入式服务器、安全、心跳检查、外部配置等。

Spring Boot 特性

  • 使用 Spring 项目引导页面可以在几秒构建一个项目;
  • 方便对外输出各种形式的服务,如 REST API、WebSocket、Web、Streaming、Tasks;
  • 非常简洁的安全策略集成;
  • 支持关系数据库和非关系数据库;
  • 支持运行期内嵌容器,如 Tomcat、Jetty;
  • 强大的开发包,支持热启动;
  • 自动管理依赖;
  • 自带应用监控;
  • 支持各种 IED,如 IntelliJ IDEA、NetBeans。

1.1.1    Spring Boot 市场热度

Spring Boot 于 2014 年发布了第一个正式版本,发布之后陆续有一些开源爱好者进行了研究,并迅速喜欢上了这款开源软件,Spring Boot 在初期低调快速发展,直到 2016 年才被真正使用起来。期间很多研究 Spring Boot 的开发者,在网上写了大量文章,推动了 Spring Boot 在行业内的发展。

从 2016 年到 2018 年,是 Spring Boot 在中国发展的黄金时期,使用 Spring Boot 的企业和个人开发者越来越多,我们从 Spring Boot 关键字的百度指数可以看出。

 

上图为 2014 年到 2018 年 Spring Boot 的百度指数,可以看出 2.0 的推出引发了搜索高峰。

通过谷歌趋势来看 Spring Boot 在美国的使用情况发现,中国和美国使用 Spring Boot 的整体频率保持一致,看来国内技术人同步全球的技术频率越来越快。

 

看到社区使用 Spring Boot 的热情,Spring 官方也非常重视 Spring Boot 的后续发展,已经把它作为公司最顶级的项目来推广,放到了官网上第一的位置,后续 Spring Boot 的发展也被看好。

 

1.1.2    Spring Boot 和微服务架构

微服务架构是在互联网高速发展,技术日新月异的变化以及传统架构无法适应快速变化等多重因素的推动下诞生的产物。互联网时代的产品通常有两类特点:需求变化快和用户群体庞大。在这种情况下,如何从系统架构的角度出发,构建灵活、易扩展的系统,快速应对需求的变化;在用户增加的同时如何保证系统的可伸缩性、高可用性,成为系统架构面临的挑战。

如果还按照以前传统开发模式,开发一个大而全的系统已经很难满足市场对技术的需求,这时候分而治之的思想被提了出来,于是我们从单独架构发展到分布式架构,又从分布式架构发展到 SOA 架构,服务不断地被拆分和分解,粒度也越来越小,直到微服务架构的诞生。

大约 2009 年开始,Netflix 完全重新定义了它的应用程序开发和操作模型,拉开了微服务探索的第一步,直到 2014 年 3 月 Martin Fowler 写的一篇文章 Microservices 以更加通俗易懂的形式为大家定义了什么是微服务架构。Martin Fowler 在文中阐述了对微服务架构的设想,认为微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。

Spring Boot 诞生时,正处于微服务概念在慢慢酝酿中,Spring Boot 的研发融合了微服务架构的理念,实现了在 Java 领域内微服务架构落地的技术支撑。Spring Boot 在开发、测试、部署、运维等方面都做了大量的优化,使用 Spring Boot 开发项目,可以快速响应需求、独立完成开发部署上线。

Spring Boot 的一系列特性有助于实现微服务架构的落地,从目前众多的技术栈对比来看它是 Java 领域微服务架构最优落地技术,没有之一。

1.1.3    为什么学习 Spring Boot ?

《精通 Spring Boot 42 讲》

Spring Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。同时它集成了大量常用的第三方库配置(如 Redis、MongoDB、JPA、RabbitMQ、Quartz 等),Spring Boot 应用中这些第三方库几乎可以零配置进行开箱即用,大部分的 Spring Boot 应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。

使用 Spring Boot 开发项目,有以下几方面优势:

  • Spring Boot 使开发变得简单,提供了丰富的解决方案,快速集成各种解决方案提升开发效率。
  • Spring Boot 使配置变得简单,提供了丰富的 Starters,集成主流开源产品往往只需要简单的配置即可。
  • Spring Boot 使部署变得简单,其本身内嵌启动容器,仅仅需要一个命令即可启动项目,结合 Jenkins、Docker 自动化运维非常容易实现。
  • Spring Boot 使监控变得简单,自带监控组件,使用 Actuator 轻松监控服务各项状态。

从软件发展的角度来讲,越简单的开发模式越流行,简单的开发模式解放出更多生产力,让开发人员可以避免将精力耗费在各种配置、语法所设置的门槛上,从而更专注于业务。这点上,Spring Boot 已尽可能地简化了应用开发的门槛。

Spring Boot 所集成的技术栈,涵盖了各大互联网公司的主流技术,跟着 Spring Boot 的路线去学习,基本可以了解国内外互联网公司的技术特点。 

1.1.4    总结

Spring Boot 是一套快速开发框架,在微服务架构的大环境下 Spring Boot 一经推出就受到开源社区的追捧。Spring Boot 有强大的生态整合能力,提供了众多的 Starters 包,非常方便 Spring Boot 集成第三方开源软件达到开箱即用的效果。

Spring Boot 和微服务架构都是未来软件开发的大趋势,越早参与,受益越大。

1.2 第1-1课:Spring Boot 产生的背景和它的设计理念

《精通 Spring Boot 42 讲》共分五大部分,第一部分是从零起步的基础内容,共4课,帮助大家快速认识 Spring Boot ,我会带领大家熟悉 Spring Boot 产生的背景和设计理念,同时也会讲解 Spring Boot 的环境搭建和项目介绍,最后以一个 Hello World 为例,来测试一下环境的搭建以及熟悉开发的流程。本章的重点内容是 Spring Boot 2.0 的新变化,如果学习过此前课程的同学可以重点关注这一节。下面我们就具体进入第一讲的内容。

要了解 Spring Boot 产生的背景,我们就必须要先了解一下 Spring 的发展史,不仅因为 Spring Boot 来源于 Spring 体系,而且 Spring Boot 的诞生和 Spring 框架的发展息息相关。

1.2.1    Spring 的发展史

时间回到 2002 年,当时正是 Java EE 和 EJB 大行其道的时候,很多知名公司都是采用此技术方案进行项目开发。这时候有一个美国的小伙子认为 EJB 太过臃肿,并不是所有的项目都需要使用 EJB 这种大型框架,应该会有一种更好的方案来解决这个问题。

他为了证明自己的想法是正确的,在 2002 年 10 月写了一本书《Expert One-on-One J2EE》,介绍了当时 Java 企业应用程序开发的情况,并指出了 Java EE 和 EJB 组件框架中存在的一些主要缺陷。在这本书中,他提出了一个基于普通 Java 类和依赖注入的更简单的解决方案。

在书中,他展示了如何在不使用 EJB 的情况下构建高质量、可扩展的在线座位预留系统。为了构建应用程序,他编写了超过 30,000 行的基础结构代码,项目中的根包命名为 com.interface21,所以人们最初称这套开源框架为 interface21,这就是 Spring 的前身。

他是谁呢?他就是大名鼎鼎的 Rod Johnson(下图),Rod Johnson 在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位,更令人吃惊的是在回到软件开发领域之前,他还获得了音乐学的博士学位。现在 Rod Johnson 已经离开了 Spring,成为了一个天使投资人,同时也是多个公司的董事,早已走上人生巅峰。

 

在这本书发布后,一对一的 J2EE 设计和开发一炮而红。这本书免费提供的大部分基础架构代码都是高度可重用的。2003 年 Rod Johnson 和同伴在此框架的基础上开发了一个全新的框架命名为 Spring,据 Rod Johnson 介绍 Spring 是传统 J2EE 新的开始,随后 Spring 发展进入快车道。

  • 2004 年 03 月,1.0 版发布。
  • 2006 年 10 月,2.0 版发布。
  • 2007 年 11 月,更名为 SpringSource,同时发布了 Spring 2.5。
  • 2009 年 12 月,Spring 3.0 发布。
  • 2013 年 12 月,Pivotal 宣布发布 Spring 框架 4.0。
  • 2017 年 09 月,Spring 5.0 发布。

1.2.2    Spring Boot 的诞生

多年以来,Spring 平台饱受非议的一点就是大量的 XML 配置以及复杂的依赖管理。

随着使用 Spring 进行开发的个人和企业越来越多,Spring 也慢慢从一个单一简洁的小框架变成一个大而全的开源软件,Spring 的边界不断进行扩充,到了后来 Spring 几乎可以做任何事情,市面上主流的开源软件、中间件都有 Spring 对应组件支持,人们在享用 Spring 的便利之后,也遇到了一些问题。

Spring 每集成一个开源软件,就需要增加一些基础配置,随着开发项目的逐渐庞大,往往需要集成很多开源软件。后期使用 Spring 开发大型项目需要引入很多配置文件,导致配置工作难以理解且出错率高,到了后来人们甚至称 Spring 为配置地狱。

在 2013 年的 SpringOne 2GX 会议上,Pivotal 的 CTO Adrian Colyer 回应了这些批评,并且特别提到该平台将来的目标之一就是实现免 XML 配置的开发体验。Spring Boot 所实现的功能超出了这个任务的描述,开发人员不仅不再需要编写 XML,而且在一些场景中甚至不需要编写繁琐的 import 语句。

2013 年,微服务的概念也慢慢兴起,快速开发微小独立的应用变得更为急迫,Spring 刚好处在这样一个交叉点上,于 2013 年初启动了 Spring Boot 项目的研发。2014 年,Spring Boot 伴随着 Spring 4.0 诞生发布了第一个正式版本。

Spring Boot 并不是要成为 Spring 平台里面众多“Foundation”层项目的替代者。Spring Boot 的目标不在于为已解决的问题域提供新的解决方案,而是为平台带来另一种开发体验,从而简化对这些已有技术的使用。对于已经熟悉 Spring 生态系统的开发人员来说,Spring Boot 是一个很理想的选择;对于采用 Spring 技术的新人来说,Spring Boot 提供一种更简洁的方式来使用这些技术。

1.2.3    Spring Boot 开发团队

我们经常会看到在介绍 Spring Boot 的时候有这么一句:Spring Boot 是由 Pivotal 团队提供的全新框架。由此我们得知 Spring Boot 是由 Pivotal 团队所研发,那么 Pivotal 团队到底是一个什么样的团队呢?其实这里的 Pivotal 团队是指 Pivotal 公司。

Pivotal 公司:致力于“改变世界构造软件的方式(We are transforming how the world builds software)”,提供云原生应用开发 PaaS 平台及服务,帮助企业客户采用敏捷软件开发方法论,从而提高软件开发人员工作效率、减少运维成本,实现数字化转型、IT 创新,并最终实现业务创新。

Pivotal 公司可谓是大牛云集,公司的开源产品有:Spring 以及 Spring 衍生产品、Web 服务器 Tomcat、缓存中间件 Redis、消息中间件 RabbitMQ、平台即服务的 Cloud Foundry、Greenplum 数据引擎、还有大名鼎鼎的 GemFire(12306 系统解决方案组件之一)。这些著名开源产品背后的开发者都在 Pivotal 公司,其研发团队汇集了全球的一流开发者,Spring Boot 为什么如此优秀,或许在这里可以找到一些答案。

回顾 Pivotal 公司的发展历史,简直就是一场商业并购大片:

  • 1989 年,罗伯·米创立 Pivotal Labs 公司,它的主营业务是帮助客户开发软件,曾给谷歌、Twitter 公司做技术支持;
  • 2003 年,EMC 收购了 VMware;
  • 2009 年,VMware 收购了 Spring 公司;
  • 2012 年,EMC 以现金方式收购了 Pivotal Labs 公司; 
  • 2013 年,EMC 和 VMware 分拆出其 Cloud Foundry、Pivotal Labs、Greenplum 等云计算、大数据资源,GE 投资 1.05 亿美元,成立新公司 Pivotal;
  • 2015 年,EMC 又被 DELL 所收购。

Pivotal 公司成立之后,于 2014 年发布了 Spring Boot,2015 年发布了 Spring Cloud,2018 年 Pivotal 公司在纽约上市。我们可以通过一张图来了解 Pivotal 公司的发展史。

 

《精通 Spring Boot 42 讲》

1.2.4    Spring Boot 的核心:约定优于配置

那么什么是约定优于配置呢?

约定优于配置(Convention Over Configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量、获得简单的好处,而又不失灵活性。

本质是说,开发人员仅需规定应用中不符约定的部分。例如,如果模型中有个名为 User 的类,那么数据库中对应的表就会默认命名为 user。只有在偏离这一约定时,例如将该表命名为“user_info”,才需写有关这个名字的配置。

我们可以按照这个思路来设想,我们约定 Controller 层就是 Web 请求层可以省略 MVC 的配置;我们约定在 Service 结尾的类自动注入事务,就可以省略了 Spring 的切面事务配置。

在 Spring 体系中,Spring Boot JPA 就是约定优于配置最佳实现之一,不需要关注表结构,我们约定类名即是表名,属性名即是表的字段,String 对应 varchar,long 对应 bigint,只有需要一些特殊要求的属性,我们再单独进行配置,按照这个约定我们可以将以前的工作大大简化。

Spring Boot 体系将约定优于配置的思想展现得淋漓尽致,小到配置文件、中间件的默认配置,大到内置容器、生态中的各种 Starters 无不遵循此设计规则。Spring Boot 鼓励各软件组织方创建自己的 Starter,创建 Starter 的核心组件之一就是 autoconfigure 模块,也是 Starter 的核心功能,在启动的时候进行自动装配,属性默认化配置。

可以说正是因为 Spring Boot 简化的配置和众多的 Starters 才让 Spring Boot 变得简单、易用、快速上手,也可以说正是约定优于配置的思想彻底落地才让 Spring Boot 走向辉煌。Spring Boot 约定优于配置的思想让 Spring Boot 项目非常容易上手,让编程变得更简单,其实编程本该很简单,简单才是编程的美。 

1.2.5    Starters

Spring Boot Starters 基于约定优于配置的理念来设计,Spring Boot Starter 中有两个核心组件:自动配置代码和提供自动配置模块及其它有用的依赖。也就意味着当我们项目中引入某个 Starter,即拥有了此软件的默认使用能力,除非我们需要特定的配置,一般情况下我仅需要少量的配置或者不配置即可使用组件对应的功能。

Spring Boot 由众多 Starter 组成,随着版本的推移 Starter 家族成员也与日俱增。在传统 Maven 项目中通常将一些层、组件拆分为模块来管理,以便相互依赖复用,在 Spring Boot 项目中我们则可以创建自定义 Spring Boot Starter 来达成该目的。

Spring Boot 拥有强大融合社区开源软件的能力,在没有使用 Spring Boot 之前,我们需要按照每个开源软件的特性,将对应的组件包集成到我们的开发项目中,因为每个组件的设计理念和开发团队都不一致,因此会有很多不同的调用风格在我们的项目中。

Spring Boot 整合了主流的开源软件形成了一系列的 Starter,让我们有了一致的编程体验来集成各种软件,Spring Boot 在集成的时候做了大量的优化,让我们在集成的时候往往只需要很少的配置和代码就可以完成。可以说各种 Starters 就是 Spring Boot 最大的优势之一。

以下为常用的 Spring Boot Starter 列表。

名称

描述

Pom

spring-boot-starter

核心 Starter,包括自动配置支持,日志和 YAML

Pom

spring-boot-starter-activemq

用于使用 Apache ActiveMQ 实现 JMS 消息

Pom

spring-boot-starter-amqp

用于使用 Spring AMQP 和 Rabbit MQ

Pom

spring-boot-starter-cache

用于使用 Spring 框架的缓存支持

Pom

spring-boot-starter-data-elasticsearch

用于使用 ElasticSearch 搜索,分析引擎和 Spring Data ElasticSearch

Pom

spring-boot-starter-data-jpa

用于使用 Hibernate 实现 Spring Data JPA

Pom

spring-boot-starter-data-mongodb

用于使用基于文档的数据库 MongoDB 和 Spring Data MongoDB

Pom

spring-boot-starter-data-redis

用于使用 Spring Data Redis 和 Jedis 客户端操作键—值数据存储 Redis

Pom

spring-boot-starter-jta-atomikos

用于使用 Atomikos 实现 JTA 事务

Pom

sring-boot-starter-mail

用于使用 Java Mail 和 Spring 框架 Email 发送支持

Pom

spring-boot-starter-quartz

用于定时任务 Quartz 的支持

Pom

spring-boot-starter-security

对 Spring Security 的支持

Pom

spring-boot-starter-test

用于测试 Spring Boot 应用,支持常用测试类库,包括 JUnit、Hamcrest 和 Mockito

Pom

spring-boot-starter-thymeleaf

用于使用 Thymeleaf 模板引擎构建 MVC Web 应用

Pom

spring-boot-starter-validation

用于使用 Hibernate Validator 实现 Java Bean 校验

Pom

spring-boot-starter-web

用于使用 Spring MVC 构建 Web 应用,包括 RESTful。Tomcat 是默认的内嵌容器

Pom

spring-boot-starter-websocket

用于使用 Spring 框架的 WebSocket 支持构建 WebSocket 应用

Pom

这里只节选了我们最常使用的 Starter,完整的 Starter 参考这里:Spring Boot application starters

因为 Spring Boot 足够的强大,很多第三方社区都进行了主动的集成。比如:MyBatis、RabbitMQ(高级用法)等,第三方社区支持的列表,可以在这里查看 Community Contributions,可以看到社区贡献的其他 Starters 列表。

看完这些 Starters 会不会瞬间觉得 Spring Boot 很强大?几乎我们涉及的开源软件 Spring Boot 都做了支持,在 Spring Boot 环境下使用这些软件,只需要引入对应的 Starter 包即可。

1.2.6    Spring、Spring Boot 和 Spring Cloud 的关系

Spring 最初核心的两大核心功能 Spring IoC 和 Spring Aop 成就了 Spring,Spring 在这两大核心功能上不断地发展,才有了 Spring 事务、Spring MVC 等一系列伟大的产品,最终成就了 Spring 帝国,到了后期 Spring 几乎可以解决企业开发中的所有问题。

Spring Boot 是在强大的 Spring 帝国生态基础上面发展而来,发明 Spring Boot 不是为了取代 Spring,是为了让人们更容易的使用 Spring。所以说没有 Spring 强大的功能和生态,就不会有后期 Spring Boot 的火热,Spring Boot 使用约定优于配置的理念,重新重构了 Spring 的使用,让 Spring 后续的发展更有生命力。

Spring 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装并屏蔽掉复杂的配置和实现原理,最终给开发者提供了一套简单易懂、易部署、易维护的分布式系统开发工具包。

Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发。服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

Spring Cloud 是为了解决微服务架构中服务治理而提供的具备一系列功能的开发框架,并且 Spring Cloud 是完全基于 Spring Boot 而开发,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。

综上我们可以这样来理解,正是由于 Spring IoC 和 Spring Aop 两个强大的功能才有了 Spring,Spring 生态不断的发展才有了 Spring Boot,使用 Spring Boot 让 Spring 更易用更有生命力,Spring Cloud 是基于 Spring Boot 开发的一套微服务架构下的服务治理方案。

以下为它们之间的关系。

Spring Ioc/Aop > Spring > Spring Boot > Spring Cloud

1.2.7    总结

Spring Boot 诞生一方面是因为 Spring 自身发展所遇到的问题,另一方面在微服务思想诞生之际,急需要一款快速开发工具来实现微服务技术落地,在这样的背景下诞生了 Spring Boot。

Spring Boot 整体的设计思想是:约定优于配置。依赖此设计思路,Spring Boot 进行了大刀阔斧的改革,让开发、测试、部署更为便捷。众多的 Starters 成就了 Spring Boot 的发展,让使用 Spring Boot 开发项目变得更加简单。

1.3 第1-2课:Spring Boot 2.0 都更新了什么(上)

2018 年 3 月 1 号 Spring Boot 2.0.0.RELEASE 正式发布,这是 Spring Boot 1.0 发布 4 年之后第一次重大修订,因此有多新功能和特性值得关注!在 Spring Boot 官方博客中我们了解到:Spring Boot 2.0 版本经历了 17 个月的开发,有 215 个不同的使用者提供了超过 6800 次的提交。

我们将 Spring Boot 2.0 更新的技术分为三类进行解读:

  • 第一类,基础环境升级;
  • 第二类,默认软件替换和优化;
  • 第三类,新技术的引入。

1.3.1    基础环境升级

1.3.1.1 最低 JDK 8,支持 JDK 9,不再支持 Java 6 和 7

Spring Boot 2.0 要求 Java 8 作为最低版本,许多现有的 API 已更新,以利用 Java 8 的特性。例如,接口上的默认方法,函数回调以及新的 API,如 javax.time。如果你正在使用 Java 7 或更早版本,则在开发 Spring Boot 2.0 应用程序之前,需要升级你的 JDK。

Spring Boot 2.0 通过测试可以在 JDK 9 下正常运行,同时 Spring Boot 2.0 宣布不再支持 Java 6 和 7,据我了解国内绝大部分互联网公司的基本环境还在 JDK 7 或者 6 环境下运行,考虑升级 Spring Boot 2.0 的团队需要考虑这个因素。

1.3.1.2 依赖组件升级

Spring Boot 2.0 基于 Spring Framework 5 构建,本次 Spring Boot 的升级,同时也升级了部分其依赖的第三方组件,主要有以下几个:

  • Jetty 9.4,Jetty 是一个开源的 Servlet 容器,它为基于 Java 的 Web 内容,例如 JSP 和 Servlet 提供运行环境。Jetty 是使用 Java 语言编写的,它的 API 以一组 JAR 包的形式发布。
  • Tomcat 8.5,Apache Tomcat 8.5.x 旨在取代 8.0.x,完全支持 Java 9。
  • Flyway 5,Flyway 是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。用通俗的话讲,Flyway 可以像 SVN 管理不同人的代码那样,管理不同人的 SQL 脚本,从而做到数据库同步。
  • Hibernate 5.2,Hibernate 是一款非常流行的 ORM 框架。
  • Gradle 3.4,Spring Boot 的 Gradle 插件在很大程度上已被重写,有了重大的改进。
  • Thymeleaf 3.0,Thymeleaf 3 相对于 Thymeleaf 2 有非常大的性能提升。

1.3.2    默认软件替换和优化

1.3.2.1 HikariCP

默认连接池已从 Tomcat 切换到 HikariCP,HikariCP 是一个高性能的 JDBC 连接池,Hikari 是日语“光”的意思。

HikariCP 号称是 Java 业界最快的数据库连接池,官网提供了 c3p0、dbcp2、tomcat、vibur 和 Hikari 等数据连接池的性能对比。

 

关于 Hikari 性能为什么如此突出,官网给出的说明如下:

  • 字节码精简:优化代码,直到编译后的字节码最少,这样 CPU 缓存可以加载更多的程序代码;
  • 优化代理和拦截器:减少代码,例如 HikariCP 的 Statement proxy 只有 100 行代码;
  • 自定义数组类型(FastStatementList)代替 ArrayList:避免每次 get() 调用都要进行 range check,避免调用 remove() 时从头到尾的扫描;
  • 自定义集合类型(ConcurrentBag):提高并发读写的效率;
  • 其他针对 BoneCP 缺陷的优化,比如对于耗时超过一个 CPU 时间片的方法调用的研究。

1.3.2.2 Security

Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的 Security 框架。除了常规的 Authentication 和 Authorization 之外,Spring Security 还提供了诸如 ACLs、LDAP、JAAS、CAS 等高级特性以满足复杂场景下的安全需求。

没有使用 Spring Boot 之前集成起来相对比较麻烦,而 Spring Boot 中基于 Java 配置实现 Spring Security 功能。Spring Boot 2.0 极大地简化了默认的安全配置,并使添加定制安全变得简单。

Spring Boot 2.0 非常容易使用 Spring Security 5.0 保护响应式应用,当检测到 Spring Security 存在的时候会自动进行默认配置。

1.3.2.3 OAuth 2.0

OAuth 2.0 是 OAuth 协议的延续版本,但不向后兼容 OAuth 1.0,即完全废止了 OAuth1.0。OAuth 2.0 关注客户端开发者的简易性。要么通过组织在资源拥有者和 HTTP 服务商之间的被批准的交互动作代表用户,要么允许第三方应用代表用户获得访问的权限。

OAuth 2.0 是一个授权框架,或称授权标准,它可以使第三方应用程序或客户端获得对 HTTP 服务上(如 Google、GitHub )用户帐户信息的有限访问权限。OAuth 2.0 通过将用户身份验证委派给托管用户帐户的服务以及授权客户端访问用户帐户进行工作。

Spring Boot 2.0 将 Spring Security OAuth 项目迁移到 Spring Security。不再提供单独的依赖包,Spring Boot 2.0 通过 Spring Security 5 提供 OAuth 2.0 客户端支持。

1.3.2.4 Micrometer

Micrometer 是一款监控指标的度量类库,可以让你在没有供应商锁定的情况下对 JVM 的应用程序代码进行调整。

Spring Boot 2.0 增强了对 Micrometer 的集成,不再提供自己的指标 API。依靠 micrometer.io 来满足所有应用程序监视需求。

Micrometer 包括尺寸指标的支持,当与尺寸监测系统配对时,尺寸指标可以有效访问特定的指定度量标准,并且可以在其尺寸范围内向下钻取。

指标可以输出到各种系统和开箱即用的 Spring Boot 2.0,为 Atlas、Datadog、Ganglia、Graphite、Influx、JMX、New Relic、Prometheus、SignalFx、StatsD 和 Wavefront 提供支持,另外还可以使用简单的内存中度量标准。

集成后提供 JVM 指标(包括 CPU、内存、线程和 GC)、Logback、Tomcat、Spring MVC & 提供 RestTemplate。

1.3.2.5 Redis 默认使用 Lettuce

Redis 方面默认引入了 Lettuce,替代了之前的 Jedis 作为底层的 Redis 连接方式。

Lettuce 是一个可伸缩的线程安全的 Redis 客户端,用于同步、异步和反应使用。多个线程可以共享同一个 RedisConnection,它利用优秀 Netty NIO 框架来高效地管理多个连接,支持先进的 Redis 功能,如 Sentinel、集群、流水线、自动重新连接和 Redis 数据模型。

国内使用 Jedis 的居多,看来以后要多研究 Lettuce 了。

1.3.2.6 配置属性绑定

在 Spring Boot 2.0 中,使用 Environment 绑定机制的 @ConfigurationProperties 数学已经完全彻底修改。借此机会收紧了绑定的规则,并修复了 Spring Boot 1.x 中的许多不一致之处。

新的 Binder API 也可以直接使用 @ConfigurationProperties 在代码中。例如,下面绑定 List 中的 PersonName 对象:

List<PersonName> people = Binder.get(environment)
    .bind("my.property", Bindable.listOf(PersonName.class))
    .orElseThrow(IllegalStateException::new);

配置源可以像这样在 YAML 中表示:

my:
  property:
  - first-name: Jane
    last-name: Doe
  - first-name: John
    last-name: Doe
1.3.2.6.1    转换器支持

Binding 使用了一个新的 ApplicationConversionService 类,它提供了一些额外有用的转化。最引人注目的是转换器的 Duration 类型和分隔字符串。

该 Duration 转换器允许在任一 ISO-8601 格式的持续时间,或是一个简单的字符串(如 10m,10 分钟)。现有的属性已更改为默认使用 Duration,该 @DurationUnit 注释通过设置如果没有指定所使用的单元确保向后兼容性。例如,Spring Boot 1.5 中需要秒数的属性现在必须 @DurationUnit(ChronoUnit.SECONDS) 确保一个简单的值,例如 10 实际使用的值为 10s。

分隔字符串转换允许你将简单绑定 String 到 Collection 或 Array 不必分割逗号。例如,LDAP base-dn属性用 @Delimiter(Delimiter.NONE),所以 LDAP DN(通常包含逗号)不会被错误解释。

1.3.2.7 Actuator 改进

在 Spring Boot 2.0 中 Actuator endpoints 有很大的改进,所有 HTTP Actuator endpoints 现在都在该/actuator路径下公开,并且生成的 JSON 有效负载得到了改进。

现在默认情况下不会暴露很多端点。如果你要从 Spring Boot 1.5 升级现有的应用,请务必查看迁移指南并特别注意该 management.endpoints.web.exposure.include 属性。

Spring Boot 2.0 改进了从许多端点返回的 JSON 有效负载。

现在许多端点都具有更精确地反映底层数据的 JSON。例如,/actuator/conditions终端(/autoconfig在 Spring Boot 1.5 中)现在有一个顶级 contexts 密钥来将结果分组 ApplicationContext。

1.3.2.8 测试

对 Spring Boot 2.0 中测试进行了一些补充和调整:

  • @WebFluxTest 已添加新注释以支持 WebFlux 应用程序的“slice”测试。
  • Converter 和 GenericConverter beans 现在自动扫描 @WebMvcTest 和 @WebFluxTest。
  • @AutoConfigureWebTestClient 已经添加到 WebTestClient 供测试使用,这个注释会自动应用于 @WebFluxTest 测试。
  • 增加了一个新的 ApplicationContextRunner 测试实用程序,可以很容易地测试你的自动配置,我们已将大部分内部测试套件移至此新模型。

1.3.2.9 其他

还有一些小的调整和改进:

  • @ConditionalOnBean 现在在确定是否满足条件时使用逻辑 AND 而不是逻辑 OR。
  • 无条件类现在包含在自动配置中。
  • 该 spring CLI 应用程序现在包括 encodepassword 可用于创建 Spring Security 的兼容散列密码命令。
  • 计划任务(即 @EnableScheduling)可以使用 scheduledtasks 执行器端点进行审查。
  • 该 loggers 驱动器终端现在允许你重新设置一个日志的默认级别。
  • Spring Session 用户现在可以通过 sessions 执行器端点查找和删除会话。
  • 使用 spring-boot-starter-parent 现在基于 Maven 的应用程序-parameters默认使用标志。

1.3.3    新技术的引入

1.3.3.1 支持 HTTP/2

HTTP/2 是第二代的 HTTP 协议,Spring Boot 的 Web 容器选择中 Tomcat,Undertow 和 Jetty 均已支持 HTTP/2。

相比 HTTP/1.x,HTTP/2 在底层传输做了很大的改动和优化:

  • HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
  • HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量;而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源;头压缩能够很好的解决该问题。
  • 多路复用,直白的说就是所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然通过 pipeline 也能并发请求,但是多个请求之间的响应会被阻塞的,所以 pipeline 至今也没有被普及应用,而 HTTP/2 做到了真正的并发请求。同时,流还支持优先级和流量控制。
  • Server Push:服务端能够更快的把资源推送给客户端。例如,服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求,当客户端需要的时候,它已经在客户端了。

1.3.3.2 嵌入式 Netty 服务器

由于 WebFlux 不依赖于 Servlet API,我们现在可以首次为 Netty 作为嵌入式服务器提供支持,该 spring-boot-starter-webflux 启动 POM 将拉取 Netty 4.1 和 Ractor Netty。

注意:你只能将 Netty 用作反应式服务器,不提供阻止 Servlet API 支持。

1.3.3.3 Kotlin的支持

Spring Boot 2.0 现在包含对 Kotlin 1.2.x 的支持,并提供了 runApplication,一个使用 Kotlin 运行 Spring Boot 应用程序的方法。我们还公开和利用了 Kotlin 对其他 Spring 项目(如 Spring Framework,Spring Data 和 Reactor)已添加到其最近版本中的支持。

1.3.3.4 JOOQ 的支持

JOOQ 是基于 Java 访问关系型数据库的工具包。JOOQ 既吸取了传统 ORM 操作数据的简单性和安全性,又保留了原生 SQL 的灵活性,它更像是介于 ORMS 和 JDBC 的中间层。对于喜欢写 SQL 的码农来说,JOOQ 可以完全满足你控制欲,可以是用 Java 代码写出 SQL 的感觉来。

1.3.3.5 支持 Quartz

Spring Boot 1.0 并没有提供对 Quartz 的支持,之前出现了各种集成方案,Spring Boot2.0 给出了最简单的集成方式。

1.3.3.6 响应式编程

WebFlux 模块的名称是 spring-webflux,名称中的 Flux 来源于 Reactor 中的类 Flux。Spring WebFlux 有一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好。

非阻塞的关键预期好处是能够以小的固定数量的线程和较少的内存进行扩展。在服务器端 WebFlux 支持两种不同的编程模型:

  • 基于注解的 @Controller 和其他注解也支持 Spring MVC;
  • Functional 、Java 8 Lambda 风格的路由和处理。

 

默认情况下,Spring Boot 2.0 使用 Netty WebFlux,因为 Netty 在异步非阻塞空间中被广泛使用,异步非阻塞连接可以节省更多的资源,提供更高的响应度。通过比较 Servlet 3.1 非阻塞 I/O 没有太多的使用,因为使用它的成本比较高,Spring WebFlux 打开了一条实用的通路。

使用 Spring WebFlux/WebFlux.fn 提供响应式 Web 编程支持,WebFlux 是一个全新的非堵塞的函数式 Reactive Web 框架,可以用来构建异步的、非堵塞的、事件驱动的服务,在伸缩性方面表现非常好,此功能来源于 Spring 5.0。

Spring Boot 2.0 也提供了对响应式编程的自动化配置,如 Reactive Spring Data、Reactive Spring Security 等。

点击了解《精通 Spring Boot 42 讲》

最后,Spring Boot 2.0 的新技术还有一个有意思的彩蛋设计,我们会再下一讲介绍。同时,我会详细解释一下 Spring Boot 1.0 到 Spring Boot 2.0 API 上的一些变化,以及关于是否需要升级 Spring Boot 的个人建议。

1.4 第1-2课:Spring Boot 2.0 都更新了什么(下)

1.4.1.1 彩蛋

Spring Boot 2.0 支持了动态 Gif 的启动 Logo 打印。

在 Spring Boot 1.0 项目中 src/main/resources 路径下新建一个 banner.txt 文件,文件中写入一些字符,启动项目时就会发现默认的 Banner 被替换了,到了 Spring Boot 2.0 现在可以支持 Gif 文件的打印,Spring Boot 2.0 在项目启动的时候,会将 Gif 图片的每一个画面,按照顺序打印在日志中,所有的画面打印完毕后,才会启动 Spring Boot 项目。

 

    

项目的启动 Banner 有什么用呢,在一些大的组织或者公司中,可以利用这个特性定制自己专属的启动画面,增加团队对品牌的认同感。

1.4.2    1.0 升级 2.0 API 变化

从 Spring Boot 1.0 升级到 2.0 之后,有很多的 API 已经过时,在使用的时候需要注意。

1.4.2.1 启动类 SpringBootServletInitializer

Spring Boot 部署到 Tomcat 中去启动时需要在启动类添加 SpringBootServletInitializer,2.0 和 1.0 有区别。

// 1.0
import org.springframework.boot.web.support.SpringBootServletInitializer;
// 2.0
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 
@SpringBootApplication
public class UserManageApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(UserManageApplication.class);
    }
 
    public static void main(String[] args) throws Exception {
        SpringApplication.run(UserManageApplication.class, args);
    }
}

Spring Boot 2.0 默认不包含 log4j,建议使用 slf4j。

import org.apache.log4j.Logger;
protected Logger logger = Logger.getLogger(this.getClass());

改为:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger logger =  LoggerFactory.getLogger(this.getClass());

1.4.2.2 Thymeleaf 3.0 默认不包含布局模块

Spring Boot 2.0 中 spring-boot-starter-thymeleaf 包默认并不包含布局模块,使用 Thymeleaf 对页面进行布局时,需要单独添加布局模块,如下:

<dependency>
   <groupId>nz.net.ultraq.thymeleaf</groupId>
   <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

layout:decorator 标签在 3.0 过期,推荐使用新的标签 layout:decorate 进行页面布局。

1.4.2.3 配置文件

大量的 Servlet 专属的 server.* 被移到了 server.servlet.* 下:

Old property

New property

server.context-parameters.*

server.servlet.context-parameters.*

server.context-path

server.servlet.context-path

server.jsp.class-name

server.servlet.jsp.class-name

server.jsp.init-parameters.*

server.servlet.jsp.init-parameters.*

server.jsp.registered

server.servlet.jsp.registered

server.servlet-path

server.servlet.path

原 spring.http.* 或 spring.server.* 下的一些参数,例如我用到了文件上传参数,已修改为 sping.servlet.multipart 下。

1.4.2.4 WebMvcConfigurerAdapter 过期

Spring Boot 2.0 中将原来的 WebMvcConfigurerAdapter 替换为 WebMvcConfigurer。

1.0 中的用法:

public class MyWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter

2.0 中的用法:

public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer

1.4.2.5 Spring Boot JPA 变化

去掉了 xxxOne() 方法

以前的 findOne() 方法其实就是根据传入的 ID 来查找对象,所以在 Spring Boot 2.0 的 Repository 中我们可以添加 findById(long id) 来替换使用。

例如:

User user=userRepository.findOne(Long id)

改为手动在 userRepository 手动添加 findById(long id) 方法,使用时将 findOne() 调用改为 findById(long id):

User user=userRepository.findById(long id)

delete() 方法和 findOne() 类似也被去掉了,可以使用 deleteById(Long id) 来替换,还有一个不同点是 deleteById(Long id) 默认实现返回值为 void。

Long deleteById(Long id);

改为:

//delete 改为 void 类型
void deleteById(Long id);

当然我们还有一种方案可以解决上述的两种变化,就是自定义 SQL(如下),但是没有上述方案简单,不建议使用。

@Query("select t from Tag t where t.tagId = :tagId")
Tag getByTagId(@Param("tagId") long tagId);

需要指定主键的自增策略

Spring Boot 2.0 需要指定主键的自增策略,这个和 Spring Boot 1.0 有所区别,1.0 会使用默认的策略,如果不指定自增策略会报错。

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;

分页组件 PageRequest 变化

在 Spring Boot 2.0 中 ,方法 new PageRequest(page, size, sort) 已经过期不再推荐使用,推荐使用以下方式来构建分页信息:

Pageable pageable =PageRequest.of(page, size, Sort.by(Sort.Direction.ASC,"id"));

跟踪了一下源码发现 PageRequest.of() 方法,内部还是使用的 new PageRequest(page, size, sort),只是最新的写法更简洁一些。

public static PageRequest of(int page, int size, Sort sort) {
    return new PageRequest(page, size, sort);
}

JPA 关联查询

在使用 Spring Boot 1.0 时,使用 JPA 关联查询时我们会构建一个接口对象来接收结果集,类似如下:

public interface CollectView{
   Long getId();
   Long getUserId();
   String getProfilePicture();
   String getTitle();
}

在使用 Spring Boot 1.0 时,如果没有查询到对应的字段会返回空,在 Spring Boot 2.0 中会直接报空指针异常,对结果集的检查会更加严格一些。

这只是目前升级过程中发现的一些问题,不代表 Spring Boot 2.0 升级中的所有问题,在随后的课程中会再一一介绍。

1.4.3    是否选择升级

通过以上内容可以看出 Spring Boot 2.0 相对于 1.0 增加了很多新特性,并且最重要的是 Spring Boot 2.0 依赖的 JDK 最低版本是 1.8,估计国内大多互联网公司还没有这么激进。另外一个新的重大版本更新之后,难免会有一些小 Bug 什么的,往往需要再发布几个小版本之后,才会慢慢稳定下来。

因此我的建议是,如果不是特别需要使用 Spring Boot 2.0 上面提到的新特性,就尽量不要着急进行升级,等 Spring Boot 2.0 彻底稳定下来后再使用。如果想要升级也请先从早期的版本升级到 Spring Boot 1.5X 系列之后,再升级到 Spring Boot 2.0 版本,Spring Boot 2.0 的很多配置内容和 Spring Boot 1.0 不一致需要注意。

Spring Boot 1.0 发布之后给我们带来了全新的开发模式,Spring Boot 2.0 发布标志着 Spring Boot 已经走向成熟,对 Java 领域带来的变革已经开启!

1.4.4    总结

可以看出 Spring Boot 2.0 是历时 4 年开发出来的巨作,在 Spring Boot 1.0 的基础上进行了大量的优化,淘汰了很多过期的 API,同时引入了一大批最新的技术,这些新技术在未来的一段时间内都具有引导性。在我们学习 Spring Boot 2.0 的同时,需要同时学习 Spring Boot 2.0 引入的一些新技术,不建议大家在生产环境直接进行升级,等 Spring Boot 2.0 进一步稳

posted @ 2018-09-29 14:39  小容禹  阅读(11704)  评论(0编辑  收藏  举报