书名:深入浅出Spring Boot 3.x
ISBN:978-7-115-63282-1
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
著 杨开振
责任编辑 刘雅思
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
Spring框架是Java EE开发的强有力的工具和事实标准,而Spring Boot采用“约定优于配置”的原则简化了Spring的开发,成为业界流行的微服务开发框架,被越来越多的企业采用。为了适应新潮流,本书对Spring Boot 3.x技术进行深入讲解。
本书从一个最简单的项目开始讲解Spring Boot企业级开发,其内容包含全注解下的Spring IoC和Spring AOP、数据库编程(JPA、MyBatis和JDBC)、数据库事务、NoSQL数据库(Redis和MongoDB)技术、Spring MVC、REST风格、互联网抢购业务、监控与容器部署、Spring Cloud Alibaba微服务开发等。
本书内容紧扣互联网企业的实际需求,从全注解下的Spring知识讲到Spring Boot的企业级开发,对于Java开发者,尤其是初学Spring Boot的人员和需要从传统Spring转向Spring Boot开发的技术人员,具有很高的参考价值。
当前互联网后端开发中,Java技术占据了主导地位。对于Java开发,首选框架和事实标准是Spring框架。传统的Spring开发需要使用大量的XML配置才能使Spring框架运行起来,这备受许多开发者诟病。随着Spring 4.x的发布,Spring已经完全脱离XML,只使用注解就可以运行项目。在最近几年里,互联网世界掀起了微服务热潮。微服务会将一个大的单体系统按照业务拆分为独立的系统,然后通过REST风格的请求将它们集成起来,进一步简化了分布式系统的开发。为了进一步简化Spring的开发,Spring Boot于2014年诞生了,这是一个由Pivotal团队提供的全新框架,其设计目的是简化Spring应用的搭建以及开发过程,并迎合时下流行的微服务思维,越来越多的企业选择了Spring Boot。随着2017年9月Spring 5.x的推出,2018年Spring Boot也推出了2.x版本,至此Spring Boot成为Java开发的首选。为了顺应潮流,2018年我创作了《深入浅出Spring Boot 2.x》(下文简称为2.x版),此书一经推出,就成为该领域的主流图书。不过,随着Spring Boot的不断升级,2.x版的许多知识点已经过时,所以是时候对其进行升级改版了,这就是本书的缘起。
2017年甲骨文公司正式放弃Java EE,并将其交由Eclipse基金会托管。因为版权问题,Java EE这个名称不能被沿用,于是2018年Eclipse基金会将Java EE正式改名为Jakarta EE。Jakarta EE逐渐发展为主流技术,为此Spring推出了第6版,对Jakarta EE 9进行支持,而Pivotal团队在2022年11月推出了Spring Boot 3.x正式版。于是,我决定在2.x版的基础上进行升级,讲解Spring Boot 3.x。
Spring Boot采用“约定优于配置”的规则,大部分情况下依赖它提供的starter,就可以使用默认的约定,然后通过属性文件能减少大量的代码,使开发更为简单;对于打包,Spring Boot提供了内嵌服务器和Maven(或Gradle),进一步降低了企业部署的难度;对于测试,Spring Boot提供了快速测试的环境,进一步提高了测试效率;Spring Boot还提供了监控功能,使得开发者能及时把握项目运行的健康情况。在互联网世界中,分布式已经是一种必然的趋势,而在分布式架构中,微服务架构已成为当前的主流,因此Spring Boot渐渐成为企业级开发的主流选择。但是,微服务架构所需的服务治理和相关组件的研发成本并非一般公司所能承担的,因此Spring社区还将许多微服务组件通过Spring Boot的形式封装起来,发布给大家使用,这进一步简化了企业级微服务的开发。这样,Spring Boot和Spring Cloud都站到了互联网后端开发的主流方向上。对于我国主要的微服务架构选型——Spring Cloud Alibaba,本书也会进行探讨。
随着微服务和云服务的流行,Java很多原有的优势已经不是那么突出了,甚至Java和Spring Boot 2.x原有的一些优势反倒成了累赘。我们之所以选择Spring Boot 3.x,是因为它提供了两大好处。
一是拥抱最新技术。随着时代的发展,Jakarta EE渐渐取代Java EE成为主流技术,Java 8的语法也已经严重落后于其他计算机编程语言。Spring Boot 3.x只支持Java 17及以上版本,而Java 17作为当前长期支持版本,容纳了许多新的语法,简化了开发,十分值得学习,毕竟Java 8臃肿的语法已经很难支撑项目的快速开发以及系统开发的不断迭代和交付了。
二是需要追上微服务和云服务的潮流。随着微服务和云服务的发展,越来越多的企业使用容器进行开发、测试和部署等工作。而容器的使用使得“Build once, Run anywhere”(一次构建,到处运行)成为现实,这使得Java最大的优势——“Write once, Run anywhere”(一次编写,到处运行)大大削弱了,因为计算机语言的平台无关性已经不是一个巨大的优势了。传统Java采用的是Java虚拟机解释字节码的运行模式,在微服务和云服务中,会造成两个难以解决的问题。
● Java虚拟机解释运行程序的速度太慢。这体现在启动、部署和运行上,采用云原生文件,程序可以是毫秒级启动项目,而采用Java虚拟机后,程序只能是秒级启动项目。Java虚拟机在云服务或者微服务中性能偏慢,而采用云原生文件后,可以获得很大的性能提升。这些问题在单体系统的时代并非大问题,但是在容器化的微服务和云服务时代则被开发者所诟病,因为这不利于容器的使用。
● 镜像太大,难以管理。传统Java项目需要使用Java虚拟机来运行,同时也依赖大量的第三方包,制作成为容器的镜像太大,不利于运维环节对镜像的管理。在我的测试中,只是制作一个简单的Spring Boot项目的镜像,文件大小居然达到了490 MB。大的镜像不仅占据的空间大,还会使镜像构建、部署的时间变长,运行也会变慢。
针对这两个问题,Spring Boot 3.x开始支持预先编译技术,这是一种可以将项目在运行前直接编译为二进制文件或者机器码文件的技术,这样编译出来的文件就是云原生文件了。操作系统可以直接运行编译出来的文件,且性能比传统Java虚拟机解释的运行方式要好很多。Spring Boot 3.x的预先编译技术主要采用的是甲骨文提供的GraalVM,使用它生成的云原生文件不仅可以在操作系统直接运行,性能也更佳,制作出来的容器镜像也比传统Java镜像小得多。虽然当前GraalVM技术还不够完善,且未得到广泛使用,但它是Java未来的重要发展方向之一。
Spring Boot不是要代替Spring,而是使Spring项目可以更加快速地开发、测试和部署。它采用“约定优于配置”的理念,在内部提供大量的starter,而这些starter又提供许多自动配置类,让开发者可以奉行“拿来主义”,开箱即用。虽然这样能够快速地开发、测试和部署,但是也会带来很大的问题,那就是,如果不懂Spring的原理,一旦出现开发问题,开发者就很容易陷入困境,难以找到问题的根源,产生困扰。因此,学习Spring Boot必须掌握Spring的基础知识。基于这种情况,本书结合Spring的原理讨论Spring Boot的应用。
为了更好地讨论Spring Boot的相关知识,本书内容安排如下。
● 第1章和第2章讲解Spring Boot和传统Spring开发的区别,以及如何搭建Spring Boot开发环境。
● 第3章和第4章讨论在全注解下的Spring基础IoC和AOP,让初学者可以无缝对接Spring Boot的全注解开发方式。
● 第5章和第6章讲解数据库的开发、基于SSM框架(Spring MVC+Spring+MyBatis)的流行以及数据库事务的重要性,除了讨论传统的JDBC和JPA开发,还会重点讨论和MyBatis框架的整合,以及Spring数据库事务的编程。
● 第7章和第8章主要讲解互联网中广泛使用的两种NoSQL数据库(即Redis和MongoDB),使用它们可以极大地提高系统的性能。
● 第9章至第12章主要讲解Spring Boot下的Spring MVC的各种应用。第9章初识Spring MVC,概述Spring MVC的全流程和常见的组件;第10章深入Spring MVC的开发和应用,让读者能够掌握各种Spring Web后端的开发技巧;第11章讲解如何构建REST风格的网站,因为当前各个微服务是以REST风格请求相互融合的,所以时下它已经成为一种广泛使用的风格;第12章讲解Spring Security,通过它可以保护我们的站点,使其远离各种各样的攻击,保证网站安全。
● 第13章讲解一些Spring常用的技术,如异步线程池、异步消息和定时器等,以满足企业的其他开发需要。
● 第14章讲解Spring Boot下的SSM框架(Spring MVC+Spring+MyBatis)整合,并通过抢购业务讲述互联网中的高并发与锁的应用。
● 第15章讲解Spring Boot的打包、测试、监控、预先编译和Docker容器部署技术。
● 第16章讲解基于Spring Cloud Alibaba的微服务开发,带领读者学习国内流行的微服务架构的开发。
上述内容可以让读者对Spring Boot有深入的了解,并且通过进一步学习掌握企业级应用的开发技巧。
阅读本书前,读者需要具备Java编程语言基础、Jakarta EE(Servlet和JSP)基础、前端(HTML、JavaScript和Vue)基础和数据库(MySQL、Redis和MongoDB)基础。当然读者也可以根据自己感兴趣的技术选择部分章节来学习。
本书从Spring Boot 3.x的维度全面讲解Spring基础技术(IoC和AOP)、数据访问技术、Web技术和微服务架构等,因此本书适合以下读者。
● 使用或者即将使用Spring Boot开发的人员。
● 需要从传统Spring开发转向Spring Boot开发的人员。
● 需要使用Spring Cloud开发微服务架构的人员。
● 需要了解和学习企业级Jakarta EE开发的在校师生。从这个角度来说,本书也适合作为大中专院校的教材。
通过对本书的学习,读者可以有效地提高自身的技术能力,并能将这些技术应用于实际学习和工作当中。当然,读者也可以把本书当作工作手册来查阅。
本书在2.x版的基础上进行如下升级。
● 全面拥抱最新且被长时间支持的技术,包括Java 17、Jakarta EE 9、Spring 6.x和Spring Boot 3.x等。
● 尽量采用Java 8之后的新语法编写代码。
● 在前端技术上,删除2.x版采用的JQuery(当前已经很少用了),采用流行的前端框架Vue推荐使用的Axios。
● 使用IntelliJ IDEA作为开发默认的IDE,而非2.x版的Eclipse。
● 增加预先编译和Docker容器部署技术的讲解,更贴近企业级微服务的应用。
● 在微服务章节,剔除2.x版中过时的Spring Cloud NetFlix,拥抱目前国内流行的Spring Cloud Alibaba。
● 在2.x版的基础上,进一步完善代码样例和技术细节。
为了帮助读者更好地阅读本书,本书对以下内容进行约定。
(1)时间长度单位采用英文简写,具体为h-时、m-分、s-秒、ms-毫秒、ns-纳秒。
(2)省略import语句和Java Bean的setter与getter方法,如下:
package com.learn.chapter7.pojo;
/*** ① imports ***/
@Alias("user")
public class User implements Serializable {
private static final long serialVersionUID = 7760614561073458247L;
private Long id;
private String userName;
private String note;
/** ② setters and getters **/
}
代码①处省略import语句,而代码②处省略Java Bean的setter()与getter()方法。
Spring Boot作为一个被高度关注的微服务开发框架,版本迭代十分频繁。本书尽可能采用最新版本,于是最终选定的Spring Boot版本是3.0.6。Spring Boot 3.x支持JDK 17及以上版本,支持Jakarta EE 9,并尽量兼容Jakarta EE 10,这些是读者在阅读本书和实践的过程中需要注意的。
本书得以顺利出版要感谢人民邮电出版社的编辑们,尤其是刘雅思编辑,她以编辑的专业精神时常鞭策我,并给予我很多建议、帮助和支持,没有编辑的付出就不会有本书的出版。
感谢我的家人对我的支持和理解,我在电脑桌前写作时,牺牲了很多本该好好陪伴他们的时光。
Spring和Spring Boot技术的使用面和涉及面十分广泛,版本更替也十分频繁,加上本人能力有限,所以书中错误之处在所难免。但是,正如没有完美的技术一样,也没有完美的书籍。尊敬的读者,如果你对本书有任何意见或建议,欢迎给我发送邮件(ykzhen2013@163.com),或者在我的CSDN博客上留言(搜索用户ykzhen2015),以便于及时修订本书的错漏。
为了更好地帮助读者学习和理解本书内容,本书还免费提供源代码下载,相关信息会发布到异步社区(https://www.epubit.com)和作者博客上,欢迎读者关注。
杨开振
2023年9月
本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。
本书提供源代码下载。要获得该配套资源,您可以扫描下方二维码,根据指引领取;
您也可以在异步社区本书页面中点击,跳转到下载界面,按提示进行操作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。
作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。
当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“发表勘误”,输入勘误信息,点击“提交勘误”按钮即可(见下图)。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。
我们的联系邮箱是contact@epubit.com.cn。
如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。
如果您有兴趣出版图书、录制教学视频,或者参与图书技术审校等工作,可以发邮件给本书的责任编辑(liuyasi@ptpress.com.cn)。
如果您来自学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。
如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接通过邮件发给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。
“异步社区”(www.epubit.com)是由人民邮电出版社创办的IT专业图书社区。异步社区于2015年8月上线运营,致力于优质学习内容的出版和分享,为读者提供优质学习内容,为作译者提供优质出版服务,实现作者与读者在线交流互动,实现传统出版与数字出版的融合发展。
“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社30余年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。
当今许多互联网企业采用Java EE技术开发自己的后端服务器,原因在于Java语言简单、安全、支持多线程、性能高以及Java EE具有多年技术积累,能够快速、安全、高性能地构建互联网项目。但是,随着Java的发展,Java EE渐渐走到了尽头,2018年Eclipse基金会正式将Java EE修改为Jakarta EE,随即从Java EE 8升级为Jakarta EE 9,而原有的Spring Boot 2.x大部分还是基于Java EE 7或Java EE 8进行开发的,就显得落后了。
随着时间到了2021年,Jakarta EE得到了长足的发展。而Java 8语法严重落后于其他语言,导致Java语言的发展也遇到了瓶颈[1]。因此,在Spring 6中,就已经决定要基于Java 17+和Jakarta EE 9进行开发,而新版的Spring Boot 3.x基于Spring 6进行开发,因此也要求基于Java 17+和Jakarta EE 9,并尽可能向上兼容Jakarta EE 10。应该说,Spring 6是Spring框架的重大升级,能够更好地支持容器和微服务的开发,并拥有更快的创新速度,这也是未来数年企业级Java发展的方向。
[1]关于Java 8和之后版本的主要语法的改进,请参考附录A.1。为了跟上潮流,本书将会广泛使用这些语法。
在开启对Spring Boot 3.x的讲解之前,让我们先回顾Spring框架的历史。
在Spring框架没有被开发出来时,J2EE[2]以Sun公司[3]制定的EJB(Enterprise Java Bean)作为标准。在“遥远”的EJB年代,开发一个EJB需要大量的接口和配置文件,直至EJB 2.0的年代,开发一个EJB还需要配置两个文件,其结果就是配置的工作量比开发的工作量还要大。EJB是运行在EJB容器中的,而Sun公司定义的JSP和Servlet却是运行在Web容器中的,于是可以想象,你需要使用Web容器来调用EJB容器的服务。这就意味着存在以下的弊端:需要增加调用的配置文件才能让Web容器调用EJB容器,与此同时需要开发两个容器,非常多的配置内容和烦琐的规范导致开发效率十分低下,这非常让当时的开发者诟病;Web容器调用EJB容器的服务这种模式,注定了需要通过网络传递,因此性能不佳;测试人员还需要了解许多EJB烦琐的细节,才能进行配置和测试,这样使测试也难以进行。
[2]J2EE(Java 2 Platform, Enterprise Edition)是Java 2推出时对Java 2企业级应用的简写,是Jakarta EE的前身。
[3]Sun公司已经被甲骨文(Oracle)公司收购,不复存在。不过为了纪念该公司为Java开发做出的巨大贡献,本书还是保留这个名称。
就在大家诟病EJB的时候,2002年,澳大利亚工程师Rod Johnson(论学历他应该是音乐家,因为他是音乐博士)在其著名的著作Expert One-on-One J2EE Design and Development中提出了Spring的概念。按书中的描述,他对Spring框架的描述如下:
We believe that:
J2EE should be easier to use.
It is best to program to interfaces, rather than classes. Spring reduces the complexity cost of using interfaces to zero.
JavaBean offers a great way of configuring applications.
OO design is more important than any implementation technology, such as J2EE.
Checked exceptions are overused in Java. A platform should not force you to catch exceptions you are unlikely to recover from Testability is essential and a platform such as spring should help make your code easier to test.
We aim that:
Spring should be a pleasure to use.
Your application codes should not depend on Spring APIs.
Spring should not compete with good existing solutions, but should foster integration.
2004年,由Rod Johnson主导的Spring项目推出了1.0版本,这彻底地改变了J2EE开发的世界,很快人们就抛弃了繁重的EJB的标准,迅速地投入Spring框架中,于是Spring成为现实中J2EE开发的标准。Spring以强大的控制反转(inversion of control,IoC)来管理各类Java资源,从而降低了各种资源的耦合。Spring还提供了极低的侵入性,也就是使用Spring框架开发的编码脱离了Spring API也可以继续使用。Spring的面向方面的程序设计[4](aspect-oriented programming,AOP)通过动态代理技术,允许我们按照约定进行配置编程,进而增强了Bean的功能,并擦除了大量重复的代码,如数据库编程所需的大量try...catch...finally...语句以及数据库事务控制代码逻辑,使得开发者能够更加集中精力于业务开发,而非资源功能性的开发。Spring还整合了许多当时非常流行的框架的模板,如持久层Hibernate的HibernateTemplate模板、iBATIS的SqlMapClientTemplate模板等,极大地融合并简化了当时主流技术的使用,展现出强有力的生命力,并延续至今。
[4]旧称为“面向切面编程”,根据《计算机科学技术名词》(第三版),现规范用语为“面向方面的程序设计”。
值得一提的是,EJB 3.0的规范也引入了Spring的理念,并整合了Hibernate框架的思想,但是并未能挽回其颓势,主要原因在于EJB 3.0的规范仍然比较死板,而且难以整合其他开源框架。此外,它运行在EJB容器之中,使用起来还是比较困难,性能也不高。
随着技术的发展,2005年Sun公司正式将J2EE更名为Java EE(Java Platform, Enterprise Edition),甲骨文公司在2009年收购了Sun公司,后续宣布放弃Java EE,将其交由Eclipse基金会接手。但是由于版权方面的问题,Java EE这个名称无法保留,最终Eclipse基金会在2018年将Java EE正式更名为Jakarta EE,并延续至今。
2017年9月,Spring已经正式升级到了Spring 5,但是它只能支持Java EE 7/Java EE 8的开发,并不能支持Jakarta EE 9的开发。为了能够支持日益完善的Jakarta EE 9,Spring决定升级到Spring 6。与此同时,Pivotal团队打算基于Spring 6推出Spring Boot 3.x版本,但是这些技术只能基于Java 17+的版本。之所以对Java 17进行支持,一方面是因为Java 17是一个长期支持(long term support,LST)版本,另一方面是因为Java 17也能支持目前新流行的编程语言的语法特色。
在Spring早期的开发中,主要使用XML进行配置,很快人们意识到Spring的一个巨大的缺陷——配置太多,Bean、关系数据库、NoSQL等内容都需要使用XML进行配置,导致配置文件异常繁多且臃肿,很多开发者形象地调侃Spring为“配置地狱”。
2006年JDK 5就正式引入了注解,但是功能不够强大,因此注解未能在Java开发中被广泛使用。到了2011年,JDK 7发布,注解功能得到了长足的发展,同时预期JDK 8会更进一步增强注解功能。随着注解功能的增强,用注解取代XML来减少配置,从而改变Spring成为必然。
2012年,Pivotal团队在Java 7发版后开始研究不需要XML配置文件的Spring Boot项目,并在JDK 8发版[5]后,2014年4月基于Spring 4发布了Spring Boot 1.0.0,随着后续不断地更新和完善,Spring Boot得到了广泛的接受和应用。到了2018年3月,Pivotal团队基于Spring 5发布了Spring Boot 2.0.0,至此Spring Boot成为使用Spring技术的主流方式。本书讨论的Spring Boot 3.x是2022年11月下旬发布的新一代Spring Boot版本,为了迎合新的技术潮流,它只支持Java 17+和Jakarta EE 9,并尽量兼容Jakarta EE 10,因此在应用时需要注意相应的版本问题。
[5]JDK 8发版于2014年3月。
谈到Spring Boot,我们先来了解它的特点。依据官方的文档,Spring Boot的特点如下:
● 能够创建独立的Spring应用程序;
● 能够嵌入Tomcat、Jetty或者Undertow等服务器,无须部署WAR文件;
● 允许通过Maven或Gradle来根据需要获取启动器(starter);
● 尽可能地自动配置Spring;
● 提供生产就绪型功能,如指标、健康检查和外部配置;
● 绝对没有代码生成,对XML没有配置要求。
这段描述告诉我们:Spring Boot项目可以看作一个基于Spring框架搭建起来的独立应用;Spring Boot能够嵌入Tomcat、Jetty或者Undertow等服务器,并且不需要部署传统的WAR文件,也就是说搭建Spring Boot项目并不需要单独下载Tomcat等传统的服务器;Spring Boot提供通过Maven(或者Gradle)依赖的starter,这些starter可以直接获取开发所需的相关包,通过这些starter项目就能以Java Application的形式运行Spring Boot项目;对于配置,Spring Boot提供Spring框架的最大自动化配置,大量使用自动配置,尽量减少开发者对Spring的配置;Spring Boot提供一些监测、自动检测的功能和外部配置功能;Spring Boot没有任何附加代码和XML的配置要求。
“约定优于配置”是Spring Boot的主导思想。Spring Boot应用大部分情况下存在默认配置,开发者甚至可以在没有任何定义的情况下使用Spring框架,如需自定义,一般使用配置文件即可,十分便捷。对于部署这些项目必需的功能,Spring Boot提供starter的依赖,例如,spring-boot-starter-web不仅会捆绑Spring MVC依赖的包,还会捆绑内嵌的Tomcat服务器,这样使得开发者能够尽可能快地搭建开发环境,快速进行开发、部署和测试,这就是Spring Boot的特色。
也许作为传统开发者的读者还未能理解Spring Boot,但这并不要紧。为了让大家体会Spring Boot的特色,本章将介绍一个简单的Spring Boot工程的开发。
Spring Boot的目的不是摆脱Spring框架,而是使Spring框架更容易使用。从这句话可以看出,Spring Boot是基于Spring框架开发出来的,目的是让开发者更方便地使用Spring开发、部署和监控应用程序。
从实际的角度来看,使用Spring Boot的前提是掌握好Spring的原理,如果没有掌握好Spring的原理就仓促地使用Spring Boot,在遇到实际问题时就很容易陷入困境。基于这个原因,本书不但会讲解Spring Boot的应用,也会讲解Spring的原理。只有理解了Spring的原理,我们才能理解Spring Boot为我们做了哪些配置,而这些配置又有什么用,也只有将Spring Boot的实践和Spring的原理结合起来,才可以用好Spring Boot,从而解决工作和学习上遇到的问题。
使用Spring Boot进行开发后,你就会发现原来一切可以那么简单,因为它开箱即用。不过在入门阶段我们暂时不需要讨论太多的细节问题,这是未来需要讨论的,这里只是让大家体验Spring Boot的开发是多么简单。首先,我们在IDE中创建一个Maven项目,定义其名称为chapter1,这样就可以看到一个Maven配置文件pom.xml,对其内容进行代码清单1-1所示的修改。
代码清单1-1 通过Maven配置Spring Boot依赖
<?xml version="1.0" encoding="UTF-8"?>
<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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>springboot3</groupId>
<artifactId>chapter1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>chapter1</name>
<description>chapter1</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
从加粗的代码中可以看到,Maven的配置文件引入了多个Spring Boot的starter,Spring Boot会根据Maven配置的starter来寻找对应的依赖,将对应的jar包加载到项目中,spring-boot-starter-web还会捆绑内嵌的Tomcat服务器,并将它加载到项目中,这些都不需要开发者再进行处理。正如Spring Boot承诺的那样,绑定服务器,并且采用“约定优于配置”的原则,尽可能配置好Spring。这里只需要开发一个类就可以运行Spring Boot的应用了,为此新建类Chapter1Main,如代码清单1-2所示。
代码清单1-2 开发Spring Boot应用
package com.learn.chapter1.main;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
// Spring MVC控制器
@Controller
// 启用Spring Boot自动装配
@SpringBootApplication
public class Chapter1Main {
@RequestMapping("/test")
@ResponseBody
public Map<String, String> test() {
var map = new HashMap<String, String>();
map.put("key", "value");
return map;
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Chapter1Main.class, args);
}
}
好了,这个入门实例已经完结了。如果你没有接触过Spring Boot,那么你会十分惊讶,这样就配置完成Spring MVC的内容了吗?我可以回答你:“是的,已经完成了,现在你完全可以使用Java Application的形式来运行类Chapter1Main了。”下面是Spring Boot的运行日志:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.12)
2022-11-26T10:02:04.942+08:00 INFO 15448 --- [ main]
com.learn.chapter1.main.Chapter1Main : Starting Chapter1Main using Java 18.0.1 with
PID 15448 (F:\spring boot 3\chapter1\target\classes started by ASUS in F:\spring boot
3\chapter1)
2022-11-26T10:02:04.944+08:00 INFO 15448 --- [ main]
com.learn.chapter1.main.Chapter1Main : No active profile set, falling back to 1 default
profile: "default"
2022-11-26T10:02:05.777+08:00 INFO 15448 --- [ main]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-11-26T10:02:05.790+08:00 INFO 15448 --- [ main]
o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-11-26T10:02:05.790+08:00 INFO 15448 --- [ main]
o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache
Tomcat/10.1.1]
2022-11-26T10:02:05.878+08:00 INFO 15448 --- [ main]
o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded
WebApplicationContext
2022-11-26T10:02:05.880+08:00 INFO 15448 --- [ main]
w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization
completed in 890 ms
2022-11-26T10:02:06.159+08:00 WARN 15448 --- [ main]
ion$DefaultTemplateResolverConfiguration : Cannot find template location:
classpath:/templates/ (please add some templates, check your Thymeleaf configuration, or
set spring.thymeleaf.check-template-location=false)
2022-11-26T10:02:06.225+08:00 INFO 15448 --- [ main]
o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with
context path ''
2022-11-26T10:02:06.233+08:00 INFO 15448 --- [ main]
com.learn.chapter1.main.Chapter1Main : Started Chapter1Main in 1.625 seconds
(process running for 1.938)
从运行日志中可以看到,Tomcat服务器已经启动,因此,接下来就可以进行测试了。打开浏览器,在地址栏输入http://localhost:8080/test,可以看到图1-1所示的结果。
图1-1 Spring Boot运行结果
这与传统的Spring应用开发是不是很不一样呢?从上面的开发过程可以看出,Spring Boot允许开箱即用,这就是它的优势。传统Spring开发需要的配置,Spring Boot都进行了约定,也就是开发者可以直接以Spring Boot约定的方式开发和运行你的项目。当开发者需要修改配置的时候,Spring Boot也提供了很多配置项给开发者进行自定义,正如它承诺的那样,尽可能地配置好Spring项目和绑定内置服务器,使得开发者需要做的内容尽可能地减少,开箱就能直接开发项目。对于部署和测试,Spring Boot也提供了默认的配置,使得部署和测试的工作更容易进行。Spring Boot还提供了监控的功能,让我们能查看应用的健康情况。
随着云时代的到来,微服务架构[6]成为市场的热点。为了支持微服务的开发,Pivotal团队构建了Spring Cloud来实现微服务架构。Spring Cloud的架构涉及很多实现微服务架构所需的组件,如服务治理中心、负载均衡、网关和断路器等。Spring Cloud并不会局限于自己开发实施微服务架构所需的组件,而更多的是采取“拿来主义”,将那些通过长时间和大量实践证明实用的组件通过Spring Boot进行封装并发布,供开发者使用,可见学习Spring Cloud的基础就是Spring Boot。有些开发者还会将来自同一个企业的多个组件通过Spring Boot封装起来,整合形成套件并发布,例如国内流行的Spring Cloud Alibaba套件、国外流行的微软公司交由VMWare托管的Spring Cloud Azure套件和美国奈飞(NetFlix)公司的Spring Cloud Netflix套件等。
[6]微服务架构是实施分布式系统的一种方式,它需要满足一定的设计风格,这些会在第16章进行讲解。