三年等来兔子书,一次性打包学透 Spring
Posted 哪 吒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三年等来兔子书,一次性打包学透 Spring相关的知识,希望对你有一定的参考价值。
目录
专栏导读
🏆作者简介:哪吒,CSDN2022博客之星Top1、CSDN2021博客之星Top2、多届新星计划导师✌、博客专家💪 ,专注Java硬核干货分享,立志做到Java赛道全网Top N。
🏆本文收录于Java基础教程系列(进阶篇),本专栏是针对大学生、初级Java工程师精心打造,针对Java生态,逐个击破,不断学习,打通Java技术栈。
🏆订阅后,可以阅读Java基础教程系列(进阶篇)中全部文章,包含Java基础、Java高并发、Spring、MySQL等Java进阶技术栈。
🏆还可以订阅其姐妹篇,Java基础教程系列,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。
🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。
🏆面试福音:10万字208道Java经典面试题总结(附答案)
摘要
作为最早在国内推动 Spring 发展的程序员之一,我被经常问到的问题就包括:帮忙推荐些 Spring 的学习资料吧!这个时候,谨慎起见,我总是推荐官方文档。时光飞逝,在接触 Java 一线开发近 20 年之后,我有幸出版了自己的新书《学透Spring:从入门到项目实战》。因为封面上有一只萌萌的兔子,我们就喊它兔子书吧。今天,我们就来聊聊兔子书的故事,以及我为什么愿意为 Java 程序员推荐兔子书。
一、写 作 缘 起
自从2004年Spring Framework 1.0正式发布后,Spring就一路高歌猛进,已然成为Java EE开发的事实标准。从诞生之初缺少相关的中文材料,一份翻译的官方文档都显得弥足珍贵,到现在铺天盖地的文章、图书与视频,Spring相关的学习资料可谓“琳琅满目”。素材虽然很多,可是它们的质量却良莠不齐。运用这些资料学习,给学习者带来了不少“副作用”。因此,每当有人让我推荐些Spring的资料时,我都会告诉他,保险起见还是去看官方文档吧。
不过,官方文档也有自己的问题,内容繁杂,读者一个组件都学不过来,何况一站式打包学习整个 Spring 家族?
在2018年底的QCon大会上,极客时间找到我希望做一门Spring的视频课程,当初最困扰我的问题就是:“已经有了这么多学习资料,还需要再做个课程吗?”那时我并没有明确的答案,但选择了优先完成课程的制作。2019年初,课程上线没几天,视频课程的订阅数就突破了1万人次。原来有不少人希望有这样一门课程,带着大家一路学习,答疑解惑。到这个时候,我才确定:需求是真实存在的。大家的学习热情和订阅数就是对我之前的问题最好的回答(截至写稿期间,订阅人数已经超过 85000)。
当图灵的编辑找到我,希望能写本原创的Spring图书时,又经历了这样一个类似的阶段。但有了之前的经验,“写不写”的思想斗争的时间并不长,更多则是在思考如何才能写出一本大家都能用得上的好书。
如何才能用得上,如何才能叫好?我和编辑老师思考这个问题的过程就为这本书的特色打好了腹稿。
二、这是一本什么样的书
希望本书能够在以下几个方面给大家带来“与众书不同”的体验。
1、内容全面且细致
本书希望能够将在日常工作中用到的 Spring 家族成员一次性全部收入囊中,包括但不限于 Spring Framework、Spring Boot、Spring Security、Spring Data 和Spring Cloud。Spring 家族成员数量“繁多”,很多朋友学习过程中遇到的一大问题就是需要找上一堆书,而不同图书之间的知识点不好衔接,学习的过程可谓“东一榔头西一榔头”,找不到学习的主线,最终的结果可能就是学了个“寂寞”。这本书的首要目标就是要帮助大家做到“学习一本书就能够解决工作中的大部分问题”。
2、 主题实用且本土化
书中的内容要贴近实际的工作场景。除了基础知识,书中更多的是那些能够拿来就用的内容,我们需要的是解决实际问题。例如,关于如何配置 DataSource,一般的书告诉大家能连上数据库就行了,但本书中专门安排了一节告诉大家如何加密连接用的密码、如何记录执行的 SQL 摘要日志等技巧。此外,与国外引进的作品不同,本书的内容相对更本土化一些,除了 Spring 本身,书中还加入了一些在国内使用相对较多的项目。例如,在国内,MyBatis 似乎比 Hibernate 更受大家的青睐,各家大厂都在重度使用。书中不仅介绍了 MyBatis,还介绍了让它如虎添翼的周边工具。在国内,阿里巴巴的 Druid 和 Dubbo 也有不少用户,很多公司都选择将 Dubbo 作为内部 RPC 的框架。此外,Spring Cloud Alibaba 也是一定不能错过的内容,无论你是否使用阿里云的服务,都应该对它有所了解,书中介绍了 Nacos 和 Sentinel 的具体用法。
3、例系统且完善
想要更好地理解书中的知识点,没有什么比生动的示例更有效的了。除了简单的代码示例,本书还特别设计了一个贯穿全书的“大型”二进制奶茶店项目案例。随着书中内容的演进,奶茶店功能逐渐丰富,越来越接近真实世界的线上奶茶店。跟着我们的演示,你就能轻松地搭建出一套完整的分布式系统。如果你的需求比较简单,对系统没有太高的要求,也许可以复制二进制奶茶店的代码,拿来就用。
4、知识有趣且深刻
如果只是介绍 Spring 家族成员的各种使用方法,那未免有些无趣,遇到一些知识点时,我们还要由点及面,多介绍些相关的信息,包括但不限于背景知识、实用技巧、常见问题、实现原理等。例如,在介绍事务时,我们会聊声明式事务背后的原理;在处理金额时,我们会聊为什么不用浮点数类型,而要使用 Money 类型;在使用 JPA 时,我们会讲解 JpaRepository 背后的实现原理;在介绍服务注册机制时,我们会了解 Zookeeper 不适合做服务注册中心的原因……这些知识点很有意思,一方面可以加深我们对相关技术点的理解,另一方面也相当于我们从正文的学习暂停片刻,进行简单的梳理和思考。所有的这些内容,我们都以“茶歇时间”的形式呈现了出来。按本书编辑的说法,这才是我全书写得最有意思的地方,大家一定不要错过书中四十余处的“茶歇时间”。
5、遗憾之处
本书也并非十全十美,由于从写作到出版的时间跨度很大(足足有两年之久),虽然过程中几次更新了相关项目的版本,但仍然没有办法做到完全与社区的最新版同步。甚至有些项目还没有发布正式版,只能放在附录里。例如,Spring Framework 6.0目前还未正式发布,为了尽量与时俱进,附录里添加了如何升级到Spring Framework 6.0和Spring Boot 3.0的说明。对于目前尚不成熟,但未来会“大有作为”的Spring Native项目,附录中也做了简单的介绍。
三、这本书的主要内容
本书的内容涉及面非常广,囊括了Spring家族中的众多产品。全书一共分为五部分,其中正文四部分共计16章内容,最后一个部分是附录。
第一部分是第1章~第5章,主要介绍Spring Framework的核心内容,即IoC容器与AOP,随后从Spring Framework过渡到Spring Boot。网上介绍IoC与AOP的资料有很多,如果你是直接上手实战的话,暂时无须在相关知识点上花费太多时间。但是,考虑到两者是整个框架的基础,书中还是用了足量的篇幅来介绍它们。
第二部分是第6章~第8章,围绕数据操作展开讨论。从最基础的JDBC操作,一直到Spring Data提供的各种封装,以及对象关系映射框架的使用,如何使用缓存等话题,都会在这部分娓娓道来。除了常见的内容,这部分内容里还提及了不少原理和实用技巧,例如Spring Framework对JDBC异常的统一处理机制,如何基于它进行定制;如何使用MyBatis的各种周边工具简化日常开发工作。
第三部分是第9章~第11章,讨论与Web开发相关的内容,包含大量日常工作中的场景。这一部分既会讨论如何使用Spring MVC开发Web系统,如何使用Spring Security来保护系统安全;也会介绍一些更高级的玩法,例如基于Spring WebFlux开发响应式Web系统、使用Spring Session来实现分布式会话等。
第四部分是第12章~第16章,主要介绍分布式系统开发涉及的内容。我们会先从微服务和云原生的概念切入,讨论什么才是符合RESTful风格的微服务;再从“道”切换入“术”,聊聊如何利用Spring Cloud和其他基础设施来开发云原生服务,其中包括服务注册与发现、服务的配置管理、服务的容错保护等诸多内容。此外,除了Spring Cloud官方支持的ZooKeeper、Consul、Resilience4j,书中还加入了阿里巴巴提供的组件的内容。
最后是附录,这里主要为那些不便放在正文中的内容做个说明。附录分为两大主题,其一是新技术,包括接下来要发布的新版本——Spring Framework 6.0和Spring Boot 3.0,还有正在快速迭代的Spring Native项目;其二是实用技巧,主要是如何将Spring Boot项目打包成能开箱即用的Docker镜像。
再次强调一下,为了帮助大家更好地学习和掌握书中的内容,本书还设计了一个贯穿全书的示例——二进制奶茶店,大家可以随着这个例子从零开始,一步步构建出一套完整的基于主流基础设施的分布式系统。
大家可通过下面的思维导图查看本书的内容。
四、如何阅读本书
既然是一本介绍Spring家族成员的书,本书的读者需要对Java有所了解,掌握Java日常开发的基本知识。
如果你是一位初学者,刚开始接触Spring,建议你跟随本书的内容脉络,一章章地进行学习,并动手实现书中的例子。由于本书的篇幅较大,如果你时间有限,建议优先阅读前三部分,并且跳过其中的第8章和第11章的进阶内容。建议大家最好是能够通读全书后再根据实际掌握情况查缺补漏。
如果你是一位有一定经验的开发者,已经用Spring开发过一些实际的项目了,可以跳过书中各个章节中的基础内容(例如第2章中的2.1节和2.2节就是IoC容器的基础知识),直接阅读2.3节和2.4节,想必你会对那里的内容更感兴趣。你可以根据自己想要了解的内容,或者是遇到的问题,直接通过目录定位到特定的章节,快速通读后,对相关内容构建个大概的认识,说不定还能直接找到答案。
无论是否有经验,我都推荐大家读读书中的“茶歇时间”。“茶歇时间”的内容包罗万象,跟相应章节的内容关联紧密,其中一部分是我个人经验、深度思考的体现(例如技巧、行业热门问题分析等),还有一部分是专门为大家学习而设计的关联知识(例如背景知识、实现原理等)。值得一提的是,“茶歇时间”也编进了目录,方便大家快速定位。
希望大家把本书作为一本关于Spring的参考手册,放在电脑边,经常翻翻,基础知识怎么巩固都不为过。
五、关于我
我是丁雪丰,一位至今仍对技术抱有极高热情的程序员,既想安安静静地做个“扫地僧”,但又安奈不住内心的冲动,想把好的技术分享给大家,所以一直在圈内各种折腾,写写书、录录课、做做分享……我最早接触 Spring 时,Spring 的版本还是 1.2,现在官方版本已经到了 6.0。毫无疑问,Spring 伴随了我的个人成长,而我的 Spring 技能也一直在进化。有幸在这个时间点上为大家带来这样一本 Spring “大部头”。鉴于封面上有一只兔子,我们将其简称为兔子书,希望大家能够喜欢兔子书。
这本书的出版得到了很多人的帮助,家人的支持、编辑的全力输出自然不必多说。在此,我特别想要感谢下国内外圈内好友这些年来对我的点拨和提携。当年是你们带我进入技术文档的翻译圈子,认识了各路大咖,很早就能接触大量业内前沿思想,时不时还能进行精彩的思想碰撞……总之,一路走来得到了太多人的帮助,感谢!
六、你们
最后,也是最重要的,必须要感谢本书真正的读者,谢谢各位愿意将自己宝贵的时间花在这本书上。在知识获取方面,哪怕本书帮上一点儿小忙,我都将不胜荣幸。但是,我更希望它能够超出你的“预期”,除了帮助你牢牢掌握 Spring,还能协助你构建完善的 Java 开发技能,养成优秀的编程习惯。
在本书的内容编写上,作为作者,我已全力以赴。现在,请大家与我同行,也请你竭尽所能——这次,我们一定要学透 Spring !
这本书上市以后,一直位居京东读者最喜欢的计算机新书 TOP5,很多读者也专门私信告诉我,新书很棒,既帮助大家熟悉了基础知识,又有不少干货。感谢大家的认可。
如果你正想入门 Spring,真正掌握落地项目实战的能力,选择兔子书,没有错,我有这个自信(👉 以下扫码购买)。还请正在阅读以及新购买图书的读者尽快学习,尽快反馈。关于内容方面的反馈,我们会力所能及地更新在重印版图书中,方便后来的学习者。
世界千变万化,始终不变的是我们需要快速学习,共勉。
在 spring-amqp 中阅读兔子消息的最早入口点是啥?
【中文标题】在 spring-amqp 中阅读兔子消息的最早入口点是啥?【英文标题】:What's the earliest point of entry to read a rabbit message in spring-amqp?在 spring-amqp 中阅读兔子消息的最早入口点是什么? 【发布时间】:2018-06-27 08:24:10 【问题描述】:我将线程本地的兔子消息数据存储在 MDC 中。我想为传入的兔子消息清除旧的并添加新的上下文数据,例如从标头中读取某些值或将兔子消息有效负载读取为byte[]
。不幸的是,我经常看到在消息到达我的 @RabbitHandler
注释方法之前发生异常。是否有一个更早的入口点可以用来建立这个上下文?我不知道在反序列化发生之前会发生什么,但理想情况下我想在尝试反序列化之前访问该消息。也许某处有一个onMessageReceived(byte[] message, Map headers)
方法挂钩。调用堆栈越早越好。
【问题讨论】:
【参考方案1】:@RabbitHandler
由 AbstractRabbitListenerContainerFactory
填充,可以通过自定义 MessageConverter
:https://docs.spring.io/spring-amqp/docs/2.0.1.RELEASE/reference/html/_reference.html#message-converters 提供。它的fromMessage()
是从MessagingMessageListenerAdapter.toMessagingMessage()
调用的。这是在MessagingMessageListenerAdapter.onMessage()
中完成的。那确实是您可以钩住的很早的地方。而且您确实仍然有一个原始的 org.springframework.amqp.core.Message
对象,没有任何转换并且具有所有可用的标头和属性。
嗯,你也可以注入:
/**
* @param afterReceivePostProcessors the post processors.
* @see AbstractMessageListenerContainer#setAfterReceivePostProcessors(MessagePostProcessor...)
*/
public void setAfterReceivePostProcessors(MessagePostProcessor... afterReceivePostProcessors)
出于类似的原因,您提出请求。
【讨论】:
看来我必须在转换器中完成它。谢谢,我试试这个。知道运行MessagingMessageListenerAdapter.onMessage()
的线程是否与执行@RabbitHandler
调用的线程相同?
确实是一样的。只需按照我提到的调用堆栈即可。
我建议setAfterReceivePostProcessors()
是最简单的路线。【参考方案2】:
一种解决方案是使用SimpleMessageListenerContainer
而不是@RabbitHandler
注释,并使用自定义消息侦听器适配器。
例子:
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter)
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter); // custom listener
container.setMessageConverter(null); // disable default conversion
return container;
@Bean
MessageListenerAdapter listenerAdapter()
RawMessageDelegate delegate = new RawMessageDelegate();
return new MessageListenerAdapter(delegate);
public class RawMessageDelegate
void handleMessage(Message message)
byte[] body = message.getBody();
MessageProperties properties = message.getMessageProperties();
Map<String, Object> headers = properties.getHeaders();
// handle raw data
【讨论】:
以上是关于三年等来兔子书,一次性打包学透 Spring的主要内容,如果未能解决你的问题,请参考以下文章
预售登上计算机新书热卖榜TOP1,开年重磅,助力Java程序员飙升核心技能