本书章节编排合理,深入浅出地阐述了 Spring Boot 2.x 的原理与应用,以及当今较为流行的微服务 系统经常用到的技术及原理,内容通俗易懂。以互联 网常见的高并发场景作为实践案例,在同类书籍中更 是难得一见。Java 工程师、架构师一定不能错过本书。 ——梁华辉 源讯信息技术(香港)有限公司系统分析师 本书从原理到实践,详细介绍了 Spring Boot 的 方方面面。无论你是 Java 新手,还是 Spring 老兵, 本书都是非常值得一读的。 ——谭茂华 资深 Java 研发(管理)专家 本书详细介绍了Spring Boot 2.x的重要知识点, 循序渐进地讲述了 Spring Boot 2.x 的开发技巧,还 提供了恰当的案例参考,非常适合想要入门和深入学 习 Spring Boot 的开发人员阅读。 ——李如先 前海联易融金融服务有限公司技术总监 本书非常全面地介绍了使用 Spring Boot 2.x 进 行 Java Web 开发的方方面面。本书可以帮助刚接触 当前互联网技术盛行,以 Spring 框架为主导的 Java 互联网技术成了主流,而基于 Spring 技术衍生 出来的 Spring Boot,采用了“约定优于配置”的思 想,极大地简化了 Spring 框架的开发。随着近些年 来微服务技术的流行,Spring Boot 也成了时下炙手 可热的热点技术。2017 年 9 月,Spring 框架出现了 重大版本升级,从 4.x 版本升级为了 5.x 版本,随着 这次升级,Spring Boot的版本也在2018年3月从1.x 升级到了 2.x。 本书重点讲解 Spring Boot 2.x 技术,首先通 过 与 传 统 Spring MVC 开 发 进 行 对 比 让 读 者 融 入 Spring Boot 的开发中,然后再分别介绍全注解下 的 Spring IoC 和 AOP、结合 MyBatis 框架详解数 据库编程和其事务开发、流行的 NoSQL(Redis 和 MongoDB)技术、Spring MVC 技术、REST 风格 网站搭建、Spring Security 技术、Spring 5.x 新发 布的 WebFlux 技术、高并发与锁、打包、测试、监 控和 Spring Cloud 入门等内容,从而帮助读者掌握 企业级 Spring Boot 开发的要点。 本书涵盖的内容从理论到互联网微服务后端的 实践,无论是 Java 互联网后端开发人员,或是从传 统 Spring 项目转向 Spring Boot 的开发人员,还是 Java 微服务开发人员,都可以从本书中获益。 分类建议:计算机/程序设计/Java 人民邮电出版社网址:www.ptpress.com.cn 封面设计:董志桢 深 入 浅 出S p rin g B o o t Spring Boot 2.x 的开发人员快速掌握这门技术,是学 习 Spring Boot 2.x 的优秀参考书籍。 ——王江平 NAVER China 高级 Java 工程师 互联网行业发展迅速,互联网后端开发是以基于 Java 的 Spring 框架为主导的,Spring Boot 极大地 简化了 Spring 框架的开发,成为市场上的主流微服务 技术。本书是作者深入研究和实践并结合自己多年的 工作经验编写而成的,系统地介绍了 Spring Boot 2.x 的基础理论和应用实践,内容由浅入深,非常值得一读。 ——尹胜 武汉群益信联软件有限公司 CEO 本书作者是一位经验丰富的资深 Java 工程师。 本书从 Spring 基础知识开始,然后通过案例深入地 介绍了 Spring Boot 2.x 的原理和实践,最后还介绍 了企业开发中主流的微服务框架等内容。对想要学习 Spring Boot 2.x 的 Java 开发人员来说,本书是一本 非常好的参考资料。 ——彭旭 前天猫资深 Java 开发工程师,现魅族架构师 杨开振 精通 Java 互联网技术开发和实践,拥 有十余年一线企业开发经验,著有业内 畅销书《深入浅出 MyBatis 技术原理 与实战》和《Java EE 互联网轻量级 框架整合开发——SSM 框架(Spring MVC+Spring+MyBatis) 和 Redis 实 现 》,目前成为自由职业人,在淘宝教 育平台上从事 Java EE 互联网相关的 在线培训工作。 从理论到实践,全面介绍 Spring Boot 的原理和应用 以高并发场景作为实践案例,循序渐进阐述 Spring Boot 实用技巧 结合主流持久层框架 MyBatis,讲述企业级 Spring Boot 开发要点 杨开振 著 来自一线开发者的实战经验总结 赠送作者讲解的部分配套视频课程 深入浅出 Spring Boot 2 .x 2 .x 深入浅出 Spring Boot 2 .x 作者在线课程本书免费视频 FM48638深入浅出Spring Boot 2.x.indd 1-5 18-7-2 下午1:21
人 民 邮 电 出 版 社 北 京 杨开振 著 深入浅出 Spring Boot 2 .x FM48638深入浅出Spring Boot 2.x.indd 11 18-7-2 下午1:22
内 容 提 要 Spring 框架是 Java EE 开发的强有力的工具和事实标准,而 Spring Boot 采用“约定优于配置”的 原则简化了 Spring 的开发,从而成为业界最流行的微服务开发框架,已经被越来越多的企业采用。2018 年 3 月 Spring Boot 的版本正式从 1.x 升级到了 2.x,为了适应新潮流,本书将对 Spring Boot 2.x 技术进 行深入讲解。 本书从一个最简单的工程开始讲解 Spring Boot 企业级开发,其内容包含全注解下的 Spring IoC 和 AOP、数据库编程(JDBC、JPA 和 MyBatis)、数据库事务、NoSQL(Redis 和 MongoDB)技术、Spring MVC、Spring 5 新一代响应式框架 WebFlux、互联网抢购业务、部署与监控、REST 风格和 Spring Cloud 分布式开发等。 本书内容紧扣互联网企业的实际要求,从全注解下 Spring 知识讲到 Spring Boot 的企业级开发,对 于 Java 开发人员,尤其是初学 Spring Boot 的人员和需要从传统 Spring 转向 Spring Boot 开发的技术人 员,具有很高的参考价值。 著 杨开振 责任编辑 杨海玲 责任印制 焦志炜 人民邮电出版社出版发行 北京市丰台区成寿寺路 11 号 邮编 100164 电子邮件 315@ptpress.com.cn 网址 http://www.ptpress.com.cn 北京鑫正大印刷有限公司印刷 开本:8001000 1/16 印张:27.75 字数:686 千字 2018 年 8 月第 1 版 印数:1 – 4 000 册 2018 年 8 月北京第 1 次印刷 定价:99.00 元 读者服务热线:(010)81055410 印装质量热线:(010)81055316 反盗版热线:(010)81055315 广告经营许可证:京东工商广登字 20170147 号
前 言 本书的缘起 当前互联网后端开发中 Java EE 占据了主导地位。对于 Java EE 开发,首选框架和事实标准是 Spring 框架。在传统的 Spring 开发中需要使用大量的 XML 配置才能使 Spring 框架运行起来,这备 受许多开发者诟病。随着 Spring 4.x 的发布,Spring 已经完全可以脱离 XML,只使用注解就可以运 行项目。近两三年里,互联网世界掀起了“微服务”热潮。“微服务”将一个大的系统拆分为多个子 系统,然后通过 REST 风格的请求将它们集成起来,进一步简化了分布式系统的开发。为了进一步 简化 Spring 的开发,2014 年 Spring Boot 诞生了,它是一个由 Pivotal 团队提供的全新框架,其设计 目的是简化 Spring 应用的搭建以及开发过程,并迎合时下流行的微服务思维,越来越多的企业选择 了 Spring Boot。随着 2017 年 9 月 Spring 5.x 的推出,2018 年 Spring Boot 也推出了 2.x 版本,进入 2.x 版本时代。 基于这样的趋势,在我和朋友合作创作完成《Java EE 互联网轻量级框架整合开发:SSM 框架 (Spring MVC+Spring+MyBatis)和 Redis 实现》后,收到了许多的读者、前同事和业内朋友的建议, 他们希望我创作一本关于 Spring Boot 的书,来给需要学习 Spring Boot 的从业人员提供参考,这就是 创作本书的缘起。Spring Boot 采用了“约定优于配置”的规则,大部分情况下依赖它提供的 starter 后,就可以使用默认的约定,加上属性文件,做大量的自定义配置,使开发更为简单;对于部署, Spring Boot 提供了内嵌服务器,和 Maven(或 Grandle)打包,进一步降低了企业部署的难度;对于 测试,它提供了快速测试的环境,进一步提高了开发效率,因此它渐渐成为中小型企业甚至是一些 大型企业开发的主流选择。加之在互联网世界中,分布式已经是一种必然的趋势,而分布式的治理 和组件研发成本并非一般公司所能承担,为此 Spring 社区还在 Spring Boot 的基础上提供了 Spring Cloud 分布式开发组件,从而进一步简化了企业级分布式开发,这让 Spring Boot 和 Spring Cloud 都 站到了互联网后端开发的主流方向上,越来越受到企业的青睐。 本书的安排 Spring Boot 不是代替 Spring,而是使 Spring 项目可以更加快速地开发、部署和测试。它采用了 “约定优于配置”的理念,在其内部提供了大量的 starter,而这些 starter 又提供了许多自动配置类, 让开发者可以奉行“拿来主义”,开箱即用。虽然这样能够快速地开发、部署和测试,但是也会带来 很大的问题,那就是,如果不懂 Spring 的原理,一旦出现开发的问题,开发者就很容易陷入困境, 难以找到问题的根源,造成开发者的困扰。所以要学习 Spring Boot 就必须掌握 Spring 的基础知识。 基于这种情况,本书会结合 Spring 的原理讨论 Spring Boot 的应用。
2 前言 为了更好地讨论 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 章和第 10 章讲解在 Spring Boot 和全注解下的 Spring MVC 开发,从 Spring MVC 的基础 讲到实际的开发和应用,让读者能够掌握各种 Spring Web 后端的开发技巧。 • 第 11 章讲构建 REST 风格的网站。因为当前各个微服务是以 REST 风格请求相互融合的, 所以时下它已经成为一种广泛使用的风格。 • 第 12 章讲 Spring Security,通过它可以保护我们的站点,使其远离各种各样的攻击,保证网 站安全,这是互联网应用必须做到的。 • 第 13 章讲一些 Spring 常用的技术,如异步线程、定时器、消息机制和 WebSocket 等,以满 足企业的其他开发需要。 • 第 14 章讲解 Spring 5 推出的新的非阻塞框架 WebFlux,介绍非阻塞编程的技巧,通过它可 以构建非阻塞的网站。 • 第 15 章讲 SSM 整合,并通过抢购场景讲述互联网中的高并发与锁的应用。 • 第 16 章讲 Spring Boot 的打包、部署、测试和监控。 • 第 17 章讲基于 Spring Cloud 的分布式开发入门知识,使用它可以构建企业级分布式系统。 上述内容可以让读者对 Spring Boot 有深入的了解,并且通过进一步学习掌握企业级应用的开 发技巧。 阅读本书的要求和目标读者 阅读本书前,读者需要具备 Java 编程语言基础、Java EE(Servlet 和 JSP)基础、前端(HTML、 JavaScript 和 JQuery)基础和数据库(MySQL、Redis 和 MongoDB)基础。当然读者也可以根据自 己感兴趣的技术选择部分章节来学习。 本书使用全注解讲解 Spring 基础技术(IoC 和 AOP),因此适合从事或者即将使用 Spring Boot 开发的人员阅读和学习,也适合基于传统 Spring 需要转向 Spring Boot 开发方式的开发者阅读,当然 也适合作为大中专院校作为教材,帮助在校师生贴近企业级 Java EE 开发。读者通过本书的学习可以 有效地提高自身的技术能力,并能将这些技术应用于实际学习和工作当中,当然读者也可以把本书 当作工作手册来查阅。
前言 3 本书使用的 Spring Boot 版本 Spring Boot 作为一个被市场高度关注的微服务开发框架,版本迭代十分频繁,这给我创作本书 带来了极大的挑战。本书出版前还有一个有趣的插曲,在本书初创时 Spring Boot 的最新正式版是 1.5.4,到我最初定稿时更新到了 1.5.9,都是基于 Spring Boot 的 1.x 版本。在 2018 年 3 月初,在书稿 进入复审环节之前,Spring Boot 发生了重大的版本更替,正式更新到了 2.x 的正式(GA)版本。为 了与时俱进,保证本书更有参考价值,我决定将本书采用的 Spring Boot 版本从最初定稿的 1.5.9 更新 到 2.0.0。因此,本书采用版本 2.0.0.RELEASE 进行讲解。Spring Boot 2.x 和 Spring Boot 1.x 在使用上 有很多地方存在很多不同,并且只能支持 JDK 8 或者以上版本,这些是读者在阅读本书和实践中需 要注意的。 致谢 本书得以顺利出版要感谢人民邮电出版社的编辑们,尤其是杨海玲编辑,她以编辑的专业精神 时常鞭策我,并给予我很多帮助和支持,没有编辑的付出就不会有本书的出版。 感谢我的家人对我的支持和理解,当在电脑桌前写书、写代码和录视频课程时,牺牲了很多本 该好好陪伴他们的时光。 感谢鼓励我编写本书的读者和朋友们,没有他们的鼓励,就不会有本书的缘起。 纠错、源码和课程 Spring 和 Spring Boot 技术的使用和涉及面十分广泛,一些技术博大精深,版本更替也十分频繁, 加上本人能力有限,所以书中错误之处在所难免。但是,正如没有完美的技术一样,也没有完美的 书籍。尊敬的读者,如果你对本书有任何意见或建议,欢迎给我发送邮件(ykzhen2013@163.com), 或者在我的博客(https://blog.csdn.net/ykzhen2015)上留言,以便于及时修订本书的错漏。 为了更好地帮助读者学习和理解本书内容,本书还提供免费的基础入门视频课程(扫封面上的 二维码在线观看)和源代码下载,相关信息会发布到异步社区(https://www.epubit.com)和作者博客 上,欢迎读者关注。 杨开振 2018 年 5 月
资源与支持 本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。 配套资源 本书提供如下资源: • 本书源代码; • 书中彩图文件。 要获得以上配套资源,请在异步社区本书页面中点击 ,跳转到下载界面,按提示进行操 作即可。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。 提交勘误 作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反 馈给我们,帮助我们提升图书的质量。 当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信 息,点击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠 异步社区的 100 积分。积分可用于在异步社区兑换优惠券、样书或奖品。
2 资源与支持 与我们联系 我们的联系邮箱是 contact@epubit.com.cn。 如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便 我们更高效地做出反馈。 如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们; 有意出版图书的作者也可以到异步社区在线提交投稿(直接访问 www.epubit.com/selfpublish/submission 即可)。 如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件 给我们。 如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内 容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护, 也是我们持续为您提供有价值的内容的动力之源。 关于异步社区和异步图书 “异步社区”是人民邮电出版社旗下 IT 专业图书社区,致力于出版精品 IT 技术图书和相关学习 产品,为作译者提供优质出版服务。异步社区创办于 2015 年 8 月,提供大量精品 IT 技术图书和电 子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网 https://www.epubit.com。 “异步图书”是由异步社区编辑团队策划出版的精品 IT 专业图书的品牌,依托于人民邮电出版 社近 30 年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的 LOGO。异步 图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。 异步社区 微信服务号
目 录 第 1 章 Spring Boot 来临 ................................ 1 1.1 Spring 的历史.............................................. 1 1.2 注解还是 XML ........................................... 2 1.3 Spring Boot 的优点 ..................................... 3 1.4 传统 Spring MVC 和 Spring Boot 的 对比 ............................................................. 4 第 2 章 聊聊开发环境搭建和基本开发 ........ 10 2.1 搭建 Spring Boot 开发环境 ...................... 10 2.1.1 搭建 Eclipse 开发环境 .................. 10 2.1.2 搭建 IntelliJ IDEA 开发环境 ........ 13 2.2 Spring Boot 的依赖和自动配置 ............... 15 2.3 使用自定义配置 ....................................... 19 2.4 开发自己的 Spring Boot 项目 .................. 21 第 3 章 全注解下的 Spring IoC..................... 23 3.1 IoC 容器简介 ............................................ 23 3.2 装配你的 Bean .......................................... 27 3.2.1 通过扫描装配你的 Bean............... 27 3.2.2 自定义第三方 Bean....................... 31 3.3 依赖注入 ................................................... 32 3.3.1 注解@Autowired ........................... 34 3.3.2 消除歧义性——@Primary 和@Quelifier.................................. 35 3.3.3 带有参数的构造方法类的装配 .... 36 3.4 生命周期 ................................................... 37 3.5 使用属性文件 ........................................... 42 3.6 条件装配 Bean .......................................... 45 3.7 Bean 的作用域...........................................46 3.8 使用@Profile .............................................48 3.9 引入 XML 配置 Bean................................50 3.10 使用 Spring EL ........................................51 第 4 章 开始约定编程——Spring AOP ........53 4.1 约定编程 ....................................................53 4.1.1 约定 ................................................53 4.1.2 ProxyBean 的实现 ..........................57 4.1.3 总结 ................................................60 4.2 AOP 的概念 ...............................................61 4.2.1 为什么使用 AOP............................61 4.2.2 AOP 术语和流程...........................64 4.3 AOP 开发详解 ...........................................65 4.3.1 确定连接点.....................................65 4.3.2 开发切面.........................................66 4.3.3 切点定义.........................................67 4.3.4 测试 AOP........................................68 4.3.5 环绕通知.........................................71 4.3.6 引入 ................................................72 4.3.7 通知获取参数.................................74 4.3.8 织入 ................................................75 4.4 多个切面 ....................................................77 第 5 章 访问数据库.........................................82 5.1 配置数据源 ................................................83 5.1.1 启动默认数据源.............................83 5.1.2 配置自定义数据源.........................83 5.2 使用 JdbcTemplate 操作数据库 ................86
2 目录 5.3 使用 JPA(Hibernate)操作数据 ............ 90 5.3.1 概述................................................ 90 5.3.2 开发 JPA......................................... 90 5.4 整合 MyBatis 框架.................................... 96 5.4.1 MyBatis 简介 ................................. 96 5.4.2 MyBatis 的配置 ............................. 97 5.4.3 Spring Boot 整合 MyBatis........... 101 5.4.4 MyBatis 的其他配置 ................... 104 第 6 章 聊聊数据库事务处理 ...................... 107 6.1 JDBC 的数据库事务............................... 108 6.2 Spring 声明式事务的使用.......................110 6.2.1 Spring 声明式数据库事务约定 ....110 6.2.2 @Transactional 的配置项.............111 6.2.3 Spring 事务管理器 .......................113 6.2.4 测试数据库事务 ...........................114 6.3 隔离级别 ..................................................118 6.3.1 数据库事务的知识 .......................118 6.3.2 详解隔离级别 .............................. 120 6.4 传播行为 ................................................. 124 6.4.1 传播行为的定义 .......................... 125 6.4.2 测试传播行为 .............................. 126 6.5 @Transactional 自调用失效问题 ........... 130 第 7 章 使用性能利器——Redis ................ 134 7.1 spring-data-redis 项目简介 ..................... 135 7.1.1 spring-data-redis 项目的设计 ...... 135 7.1.2 RedisTemplate .............................. 137 7.1.3 Spring 对 Redis 数据类型操作的 封装 .............................................. 139 7.1.4 SessionCallback 和 RedisCallback 接口 .............................................. 141 7.2 在 Spring Boot 中配置和使用 Redis ...... 142 7.2.1 在 Spring Boot 中配置 Redis....... 142 7.2.2 操作 Redis 数据类型 ................... 143 7.3 Redis 的一些特殊用法 ............................148 7.3.1 使用 Redis 事务............................148 7.3.2 使用 Redis 流水线........................149 7.3.3 使用 Redis 发布订阅....................150 7.3.4 使用 Lua 脚本 ..............................153 7.4 使用 Spring 缓存注解操作 Redis ...........156 7.4.1 缓存管理器和缓存的启用...........156 7.4.2 开发缓存注解...............................157 7.4.3 测试缓存注解...............................163 7.4.4 缓存注解自调用失效问题...........165 7.4.5 缓存脏数据说明...........................165 7.4.6 自定义缓存管理器.......................166 第 8 章 文档数据库——MongoDB .............168 8.1 配置 MongoDB........................................169 8.2 使用 MongoTemplate 实例......................170 8.2.1 搭建开发环境...............................170 8.2.2 使用 MongoTemplate 操作文档.......................................173 8.3 使用 JPA...................................................178 8.3.1 基本用法.......................................178 8.3.2 使用自定义查询...........................180 第 9 章 初识 Spring MVC.............................183 9.1 Spring MVC 框架的设计 ........................183 9.2 Spring MVC 流程 ....................................184 9.3 定制 Spring MVC 的初始化 ...................191 9.4 Spring MVC 实例 ....................................192 9.4.1 开发控制器...................................193 9.4.2 视图和视图渲染...........................194 第 10 章 深入 Spring MVC 开发 .................197 10.1 处理器映射 ............................................197 10.2 获取控制器参数 ....................................198 10.2.1 在无注解下获取参数.................199
目录 3 10.2.2 使用@RequestParam 获取 参数 ............................................ 199 10.2.3 传递数组.................................... 200 10.2.4 传递 JSON ................................. 200 10.2.5 通过 URL 传递参数 .................. 203 10.2.6 获取格式化参数 ........................ 204 10.3 自定义参数转换规则 ........................... 205 10.3.1 处理器获取参数逻辑 ................ 205 10.3.2 一对一转换器(Converter) .... 208 10.3.3 GenericConverter 集合和数组 转换 ............................................ 210 10.4 数据验证 ................................................211 10.4.1 JSR-303 验证 .............................211 10.4.2 参数验证机制 ............................ 214 10.5 数据模型 ............................................... 217 10.6 视图和视图解析器 ............................... 219 10.6.1 视图设计.................................... 219 10.6.2 视图实例——导出 PDF 文件 ............................................ 220 10.7 文件上传 ............................................... 224 10.7.1 Spring MVC 对文件上传的 支持 ............................................ 224 10.7.2 开发文件上传功能 .................... 226 10.8 拦截器 ................................................... 228 10.8.1 拦截器的设计 ............................ 228 10.8.2 开发拦截器 ................................ 229 10.8.3 多个拦截器的顺序 .................... 231 10.9 国际化 ................................................... 234 10.9.1 国际化消息源 ............................ 234 10.9.2 国际化解析器 ............................ 235 10.9.3 国际化实例 ——SessionLocaleResolver....... 237 10.10 Spring MVC 拾遗................................ 240 10.10.1 @ResponseBody 转换为 JSON 的 秘密 .......................................... 240 10.10.2 重定向...................................... 241 10.10.3 操作会话对象...........................243 10.10.4 给控制器增加通知...................245 10.10.5 获取请求头参数.......................247 第 11 章 构建 REST 风格网站 ....................249 11.1 REST 简述 .............................................249 11.1.1 REST 名词解释 ..........................249 11.1.2 HTTP 的动作..............................250 11.1.3 REST 风格的一些误区 ..............251 11.2 使用 Spring MVC 开发 REST 风格端点 ................................................251 11.2.1 Spring MVC 整合 REST ............252 11.2.2 使用 Spring 开发 REST 风格的 端点.............................................252 11.2.3 使用@RestController..................260 11.2.4 渲染结果.....................................261 11.2.5 处理 HTTP 状态码、异常和 响应头.........................................262 11.3 客户端请求 RestTemplate .....................266 11.3.1 使用 RestTemplate 请求后端 .....267 11.3.2 获取响应头、状态码和资源 交换.............................................269 第 12 章 安全——Spring Security ..............271 12.1 概述和简单安全认证 ............................271 12.2 使用 WebSecurityConfigurerAdapter 自定义 ....................................................273 12.3 自定义用户服务信息 ............................274 12.3.1 使用内存签名服务.....................275 12.3.2 使用数据库定义用户认证 服务.............................................276 12.3.3 使用自定义用户认证服务.........279 12.4 限制请求 ................................................281 12.4.1 配置请求路径访问权限.............282 12.4.2 使用 Spring 表达式配置访问 权限.............................................283
4 目录 12.4.3 强制使用 HTTPS....................... 285 12.4.4 防止跨站点请求伪造 ................ 285 12.5 用户认证功能 ....................................... 287 12.5.1 自定义登录页面 ........................ 287 12.5.2 启用 HTTP Basic 认证 .............. 288 12.5.3 登出............................................ 289 第 13 章 学点 Spring 其他的技术............... 291 13.1 异步线程池 ........................................... 291 13.1.1 定义线程池和开启异步可用 .... 292 13.1.2 异步实例.................................... 292 13.2 异步消息 ............................................... 294 13.2.1 JMS 实例——ActiveMQ........... 295 13.2.2 使用 AMQP——RabbitMQ ...... 299 13.3 定时任务 ............................................... 303 13.4 WebSocket 应用 ................................... 306 13.4.1 开发简易的 WebSocket 服务 .... 306 13.4.2 使用 STOMP...............................311 第 14 章 Spring 5 新框架——WebFlux..... 319 14.1 基础概念 ............................................... 319 14.1.1 响应式编程的宣言 .................... 320 14.1.2 Reactor 模型 .............................. 320 14.1.3 Spring WebFlux 的概述 ............. 322 14.1.4 WebHandler 接口和运行流程 ... 323 14.2 通过 Spring MVC 方式开发 WebFlux 服务端 ................................................... 325 14.2.1 开发持久层 ................................ 325 14.2.2 开发服务层 ................................ 327 14.2.3 开发控制层 ................................ 328 14.2.4 配置服务.................................... 330 14.2.5 客户端开发——WebClient ....... 331 14.3 深入 WebFlux 服务端开发 ................... 335 14.3.1 类型转换器——Converter ........ 335 14.3.2 验证器——Validator ................. 337 14.3.3 访问静态资源.............................338 14.4 深入客户端开发 ....................................339 14.4.1 处理服务端错误和转换.............339 14.4.2 设置请求头.................................341 14.5 使用路由函数方式开发 WebFlux.........342 14.5.1 开发处理器.................................342 14.5.2 开发请求路由.............................346 14.5.3 使用过滤器.................................347 第 15 章 实践一下——抢购商品.................349 15.1 设计与开发 ............................................349 15.1.1 数据库表设计.............................349 15.1.2 使用 MyBatis 开发持久层 .........350 15.1.3 使用 Spring 开发业务层和 控制层.........................................353 15.1.4 测试和配置.................................355 15.2 高并发开发 ............................................357 15.2.1 超发现象.....................................357 15.2.2 悲观锁 ........................................358 15.2.3 乐观锁 ........................................359 15.2.4 使用 Redis 处理高并发..............365 第 16 章 部署、测试和监控.........................371 16.1 部署和运行 ............................................371 16.1.1 打包 ............................................371 16.1.2 运行项目.....................................373 16.1.3 热部署 ........................................375 16.2 测试 ........................................................376 16.2.1 构建测试类.................................376 16.2.2 使用随机端口和 REST 风格测试.....................................377 16.2.3 Mock 测试 ..................................378 16.3 Actuator 监控端点 .................................379 16.4 HTTP 监控 .............................................381 16.4.1 查看敏感信息.............................382
目录 5 16.4.2 shutdown 端点 ........................... 383 16.4.3 配置端点.................................... 385 16.4.4 自定义端点 ................................ 387 16.4.5 健康指标项 ................................ 389 16.5 JMX 监控 .............................................. 392 第 17 章 分布式开发——Spring Cloud ..... 393 17.1 服务治理和服务发现——Eureka......... 395 17.1.1 配置服务治理节点 .................... 395 17.1.2 服务发现.................................... 397 17.1.3 配置多个服务治理中心节点 .... 401 17.2 微服务之间的调用 ............................... 403 17.2.1 Ribbon 客户端负载均衡 ............403 17.2.2 Feign 声明式调用.......................406 17.3 断路器——Hystrix.................................409 17.3.1 使用降级服务.............................410 17.3.2 启用 Hystrix 仪表盘...................412 17.4 路由网关——Zuul .................................415 17.4.1 构建 Zuul 网关 ...........................415 17.4.2 使用过滤器.................................418 17.5 使用@SpringCloudApplication .............421 附录 Spring Boot 知识点补充 .....................423
第 1 章 Spring Boot 来临 当今许多互联网企业采用 Java EE 的技术开发自己的后端服务器,其原因在于 Java 语言的简单、 安全、支持多线程、高性能和多年 Java EE 的技术积累,能够快速、安全、高性能地构建互联网项目。 而如果你身处于 Java EE 的领域,那么你一定听过 Spring 的大名,它是当今 Java EE 开发的事实标准, 也是绝大部分企业构建 Java EE 应用的基础。开启 Spring Boot 讲解之前,让我们先回顾 Spring Framework 的历史。 1.1 Spring 的历史 在 Spring 框架没有开发出来时,Java EE 是以 Sun 公司(已经被 Oracle 公司收购,不复存在, 但为了纪念其对 Java 发展进程的巨大影响力,全书还是保留其名称,以表致敬之意)所制定的 EJB (Enterprise Java Bean)作为标准的。在“遥远”的 EJB 年代,开发一个 EJB 需要大量的接口和配置 文件,直至 EJB 2.0 的年代,开发一个 EJB 还需要配置两个文件,其结果就是配置的工作量比开发的 工作量还要大。其次 EJB 是运行在 EJB 容器中的,而 Sun 公司定义的 JSP 和 Servlet 却是运行在 Web 容器中的,于是你可以想象得到,你需要使用 Web 容器去调用 EJB 容器的服务。这就意味着存在以 下的弊端:需要增加调用的配置文件才能让 Web 容器调用 EJB 容器;与此同时需要开发两个容器, 非常多的配置内容和烦琐的规范导致开发效率十分低下,这非常让当时的开发者诟病;对于 Web 容 器调用 EJB 容器的服务这种模式,注定了需要通过网络传递,造成性能不佳;对于测试人员还需要 了解许多 EJB 烦琐的细节,才能进行配置和测试,这样测试也难以进行。 就在大家诟病 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
2 第 1 章 Spring Boot 来临 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 版本,这彻底地改变了 Java EE 开 发的世界,很快人们就抛弃了繁重的 EJB 的标准,迅速地投入到了 Spring 框架中,于是 Spring 成为 了现实中 Java EE 开发的标准。Spring 以强大的控制反转(IoC)来管理各类 Java 资源,从而降低了 各种资源的耦合;并且提供了极低的侵入性,也就是使用 Spring 框架开发的编码,脱离了 Spring API 也可以继续使用;而 Spring 的面向切面的编程(AOP)通过动态代理技术,允许我们按照约定进行 配置编程,进而增强了 Bean 的功能,它擦除了大量重复的代码,如数据库编程所需大量的 try...catch...finally...语句以及数据库事务控制代码逻辑,使得开发人员能够更加集中精力于业务开发, 而非资源功能性的开发;Spring 还提供许多整合了当时非常流行的框架的模板,如持久层 Hibernate 的 HibernateTemplate 模板、iBATIS 的 SqlMapClientTemplate 模板等,极大地融合并简化了当时主流 技术的使用,使得其展示了强有力的生命力,并延续至今。 值得一提的是,EJB 3.0 的规范也引入了 Spring 的理念,而且整合了 Hibernate 框架的思想,但 是也未能挽回其颓势,主要原因在于它的规范还是比较死板,而且比较难整合其他开源框架。其次, 它运行在 EJB 容器之中,使用上还是比较困难,性能也不高。 1.2 注解还是 XML 只是在 Spring 早期的 1.x 版本中,由于当时的 JDK 并不能支持注解,因此只能使用 XML。而很 快随着 JDK 升级到 JDK5,它加入了注解的新特性,这样注解就被广泛地使用起来,于是 Spring 的 内部也分为了两派,一派是使用 XML 的赞同派,一派是使用注解的赞同派。为了简化开发,在 Spring 2.x 之后的版本也引入了注解,不过只是少量的注解,如@Component、@Service 等,但是功能还不 够强大,因此对于 Spring 的开发,绝大部分的情况下还是以使用 XML 为主,注解为辅。 到了 Spring 3.0 后,引入了更多的注解功能,于是在 Spring 中产生了这样一个很大的分歧,即是 使用注解还是使用 XML?对于 XML 的引入,有些人觉得过于繁复,而对于注解的使用,会使得注解 分布得到处都是,难以控制,有时候还需要了解很多框架的内部实现才能准确使用注解开发所需的功 能。这个时候大家形成了这样的一个不成文的共识,对于业务类使用注解,例如,对于 MVC 开发, 控制器使用@Controller,业务层使用@Service,持久层使用@Repository;而对于一些公用的 Bean,例 如,对于数据库(如 Redis)、第三方资源等则使用 XML 进行配置,直至今时今日这样的配置方式还在
国 1.3 Spring Boot 的优点 3 企业中广泛地使用着。也许使用注解还是 XML 是一个长期存在的话题,但是无论如何都有道理。 随着注解的功能增强,尤其是 Servlet 3.0 规范的提出,Web 容器可以脱离 web.xml 的部署,使 得 Web 容器完全可以基于注解开发,对于 Spring 3.x 和 Spring 4.x 的版本注解功能越来越强大,对于 XML 的依赖越来越少,到了 4.x 的版本后甚至可以完全脱离 XML,因此在 Spring 中使用注解开发占 据了主流的地位。与此同时,Pivotal 团队在原有 Spring 的基础上主要通过注解的方式继续简化了 Spring 框架的开发,它们基于 Spring 框架开发了 Spring Boot,所以 Spring Boot 并非是代替 Spring 框 架,而是让 Spring 框架更加容易得到快速的使用。Pivotal 团队在 2014 年推出 Spring Boot 的 1.0 版本, 该版本使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。在 2018 年 3 月 Spring Boot 推出了 2.0.0 GA 版本,该版本是基于 Spring 5 的,并引入其最新的功能,能够有效支持 Java 9 的开发。Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development) 借助 Java EE 在企业互联网的强势地位成为业界领导者,它也是近年来 Java 开发最令人感到惊喜的 项目之一。 随着近年来微服务的流行,越来越多的企业需要快速的开发,而 Spring Boot 除了以注解为主的 开发,还有其他的绑定,例如,对服务器进行了绑定和默认对 Spring 的最大化配置,所以开发者能 够尽快进行开发代码、发布和测试自己的项目。这符合了现今微服务快速开发、测试和部署的需要, 于是越来越多的企业选择 Spring Boot 作为开发的选型,进而使得 Spring Boot 更加兴旺起来。本书主 要就是论述 Spring Boot 这一令人激动的开发工具。 1.3 Spring Boot 的优点 谈到 Spring Boot,就让我们先来了解它的优点。依据官方的文档,Spring Boot 的优点如下: • 创建独立的 Spring 应用程序; • 嵌入的 Tomcat、Jetty 或者 Undertow,无须部署 WAR 文件; • 允许通过 Maven 来根据需要获取 starter; • 尽可能地自动配置 Spring; • 提供生产就绪型功能,如指标、健康检查和外部配置; • 绝对没有代码生成,对 XML 没有要求配置。 这段描述告诉我们,首先 Spring Boot 是一个基于 Spring 框架搭建起来的应用,其次它会嵌入 Tomcat、Jetty 或者 Undertow 等服务器,并且不需要传统的 WAR 文件进行部署,也就是说搭建 Spring Boot 项目并不需要单独下载 Tomcat 等传统的服务器;同时提供通过 Maven(或者 Grandle)依赖的 starter,这些 starter 可以直接获取开发所需的相关包,通过这些 starter 项目就能以 Java Application 的 形式运行 Spring Boot 的项目,而无须其他服务器配置;对于配置,Spring Boot 提供 Spring 框架的最 大自动化配置,大量使用自动配置,使得开发者对 Spring 的配置尽量减少;此外还提供了一些监测、 自动检测的功能和外部配置,与此同时没有附加代码和 XML 的配置要求。 约定优于配置,这是 Spring Boot 的主导思想。对于 Spring Boot 而言,大部分情况下存在默认配 置,你甚至可以在没有任何定义的情况下使用 Spring 框架,如果需要自定义也只需要在配置文件配 置一些属性便可以,十分便捷。而对于部署这些项目必需的功能,Spring Boot 提供 starter 的依赖,
4 第 1 章 Spring Boot 来临 例如,spring-boot-starter-web 捆绑了 Spring MVC 所依赖的包,spring-boot-starter-tomcat 绑定了内嵌 的 Tomcat,这样使得开发者能够尽可能快地搭建开发环境,快速进行开发和部署,这就是 Spring Boot 的特色。也许作为传统开发者的你,还未能理解其意义,但这并不要紧。为了展示 Spring Boot 的特 色,下节将分别展示传统 Spring MVC 项目和简易的 Spring Boot 入门实例,并进行比较。 1.4 传统 Spring MVC 和 Spring Boot 的对比 在传统的 Spring MVC 项目开发中,开发一个简易的 Spring MVC 项目,需要配置 DispatcherServlet, 也需要配置 Spring IoC 的容器。你可以选择使用 web.xml 的配置来实现,当然,如果你使用的是 Servlet 3.1 规范,也可以继承由 Spring MVC 提供的 AbstractAnnotationConfigDispatcherServletInitializer 来配置 Spring MVC 项目。这里先给出可以运行的代码示例,即使你还不熟悉 Spring MVC 也没有关 系,这里只是为了说明开发比较烦琐而已,后面将详谈 Spring MVC 的开发原理。 假设你已经导入需要的 Spring 和 Spring MVC 相关的依赖包到工程中,那么就可以开始配置 DispatcherServlet 了。例如,代码清单 1-1 就是通过继承 AbstractAnnotationConfigDispatcherServletInitializer 的方式来配置 Spring MVC 的 DispatcherServlet 的。 代码清单 1-1 配置 Spring MVC package com.springboot.springmvc.conf; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // Spring IoC容器配置 @Override protected Class<?>[] getRootConfigClasses() { // 可以返回 Spring的 Java配置文件数组 return new Class<?>[] {}; } // DispatcherServlet的 URI映射关系配置 @Override protected Class<?>[] getServletConfigClasses() { // 可以返回 Spring的 Java配置文件数组 return new Class<?>[] { WebConfig.class }; } // DispatcherServlet拦截请求匹配 @Override protected String[] getServletMappings() { return new String[] { "*.do" }; } } 注意代码中加粗的地方。这里引入了一个 Java 配置文件—— WebConfig.java,它的主要作用是 配置 Spring MVC 的核心类 DispatcherServlet 的上下文,如代码清单 1-2 所示。
国 1.4 传统 Spring MVC 和 Spring Boot 的对比 5 代码清单 1-2 配置 DispatcherServlet 的上下文 package com.springboot.springmvc.conf; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Controller; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration // 定义 Spring MVC扫描的包 @ComponentScan(value="com.*", includeFilters = {@Filter(type = FilterType.ANNOTATION, value = Controller.class)}) // 启动 Spring MVC配置 @EnableWebMvc public class WebConfig { /*** * 通过注解@Bean初始化视图解析器 * * @return ViewResolver视图解析器 */ @Bean(name = "internalResourceViewResolver") public ViewResolver initViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); return viewResolver; } /** * 初始化 RequestMappingHandlerAdapter,并加载 HTTP的 JSON转换器 * * @return RequestMappingHandlerAdapter 对象 */ @Bean(name = "requestMappingHandlerAdapter") public HandlerAdapter initRequestMappingHandlerAdapter() { // 创建 RequestMappingHandlerAdapter适配器 RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter(); // HTTP JSON转换器 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); // MappingJackson2HttpMessageConverter接收 JSON类型消息的转换 mediaType = MediaType.APPLICATION_JSON_UTF8;
6 第 1 章 Spring Boot 来临 List<MediaType> mediaTypes = new ArrayList<MediaType>(); mediaTypes.add(mediaType); // 加入转换器的支持类型 jsonConverter.setSupportedMediaTypes(mediaTypes); // 给适配器加入 JSON转换器 rmhd.getMessageConverters().add(jsonConverter); return rmhd; } } 通过上面的代码,配置完成 Spring MVC 的开发环境后,才可以开发 Spring MVC 控制器 Controller,这样就可以开发一个简单的控制器(Controller),如代码清单 1-3 所示。 代码清单 1-3 开发 Spring MVC 控制器 package com.springboot.springmvc.controller; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestController { @RequestMapping("/test") @ResponseBody public Map<String, String> test() { Map<String, String> map = new HashMap<String, String>(); map.put("key", "value"); return map; } } 这样就完成了一个传统 Spring MVC 的开发,但是你还需要第三方服务器,如 Tomcat、WebLogic 等服务器去部署你的工程。在启动服务器后,再打开浏览器,输入对应的 URL,如项目名称为 SpringMVC 则输入 http://localhost:8080/SpringMVC/test.do,就可以得到图 1-1 所示的页面。 图 1-1 测试传统的 Spring MVC 项目 从上面来看,传统的 Spring MVC 开发需要配置的内容还是比较多的,而且对设计人员要求较高。 开发完成后,开发者还需要找到对应的服务器去运行,如 Tomcat 或者 Jetty 等,这样既要进行开发, 又要进行配置和部署,工作量还是不少的。 而使用 Spring Boot 开发后,你就会发现原来一切可以那么简单。不过在入门阶段暂时不需要讨 论太多的细节问题,这是未来需要讨论的问题,所以这里只展示它是如何简单而已。首先我们在 IDE 中创建一个Maven工程,并把其名称定义为Chapter1,这样就可以看到一个Maven配置文件 pom.xml,
国 1.4 传统 Spring MVC 和 Spring Boot 的对比 7 将其内容修改为如代码清单 1-4 所示。 代码清单 1-4 配置 Spring Boot 依赖环境 <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>springboot</groupId> <artifactId>chapter1</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>chapter1 Maven Webapp</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- Spring Boot Starter依赖引入 --> <!-- AOP包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- Web开发包,将载入 Spring MVC所需要的包,且内嵌 tomcat --> <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 会根
Comments 0
Loading comments...
Reply to Comment
Edit Comment