Spring 配置类深度剖析 - 总结篇 (手绘流程图,可白嫖)
生命太短暂,不要去做一些根本没有人想要的东西。本文已被 https://www.yourbatman.cn 收录,里面一并有 Spring 技术栈、MyBatis、JVM、中间件等小而美的专栏供以免费学习。关注公众号【BAT 的乌托邦】逐个击破,深入掌握,拒绝浅尝辄止。
前言
各位好,我是 A 哥。最近写了好几篇关于 Spring @Configuration
的文章,收录在 Spring 配置类专栏里,这是本公众号的第一个专栏(虽然 CSDN 里已有几百篇)。虽然写的过程很艰难,但从评价反馈来看都是正向的,聊以安慰呗,比如这个小伙的“三宗最”让我听了很开心啊😄:
虽然每篇文章的阅读量堪忧,毕竟从第一篇文章我就对我自己的公众号定位了嘛:不求大量流行,只求小众共鸣。因为我知道愿意坚持看下去系列文章(强依赖于上下文)的小伙伴还是比较少的,但我相信一旦坚持下来我们的共同话题就多了,“臭味相投”嘛,是这样的吧~
在这之前,CSDN 里写过几百篇关于 Spring 的文章,但是总感觉体系性不够,东打一炮,西放一枪难免会有失连贯性。我一直认为大多时候技术的相关性、上下文上很必要的,仅靠一篇文章想把一个成型的知识点讲清楚几乎没可能,所以那种容易成为快餐,过眼即忘。这不这次我选择在公众号里做些成系列的专题,在 CSDN 的基础上,抽取精华,去其糟粕,以自身能力尽量的做好每一个专栏,普惠于有需要的小伙伴。过程很枯燥和很乏味,愿意看下去的人也不会很多,能坚持下来或许会被自己感动😄。
作为第一个专栏的总结篇,一般的都是少文字多流程图,旨在起到一个总览的作用,也为方便快速应付面试~
版本约定
本文内容若没做特殊说明,均基于以下版本:
JDK:
1.8
Spring Framework:
5.2.2.RELEASE
正文
本文以绘制流程图为主,特点是快,缺点是不详,辅以该专栏(关注公众号,进入该专栏。或点击顶部相关推荐直达)前几篇文章可以达到很好的效果。
相关类
@Configuration
:标注在类上,表示该类是个 Full 模式的配置类
- 自 Spring 5.2.0 版本后它加了个proxyBeanMethods
属性来显示控制 Full 模式还是 Lite 模式,默认是 true 表示 Full 模式
@Bean
:标注在方法上,表示方法生成一个由 Spring 容器管理的 BeanConfigurationClassPostProcessor
:用于引导处理 @Configuration 配置类的后置处理器。注意:它只是引导处理,并不是实际处理ConfigurationClassUtils
:内部工具类。用于判断组件是否是配置类,又或是 Full 模式/Lite 模式,然后在 bd 元数据里打上标记
- 它还会处理一件小事:获取 @Configuration 配置类上标注的 @Order 排序值并放进 bd 里
BeanMethod
:内部使用的类。用于封装标注有 @Bean 注解的方法ConfigurationClass
:内部使用的类。每一个 @Configuration 配置类都会被封装为它,内部会包含多个 @Bean 方法(BeanMethod)ConfigurationClassParser
:解析 @Configuration 配置类,最终以 ConfigurationClass 对象的形式展示,并且填充它:因为一个配置类可以@Import
导入另外一个(或者 N 多个)其它配置类,所以需要填充ConfigurationClassBeanDefinitionReader
:内部使用的类。读取给定的已经解析好的Set<ConfigurationClass>
集合,把里面的 bd 信息注册到BeanDefinitionRegistry
里去(这里决定了 bd 的有序和无序相关问题)ConfigurationClassEnhancer
:内部使用的类。配置类增强器,用于对 @Configuration 类(Full 模式)使用 CGLIB 增强,生成一个代理子类字节码 Class 对象EnhancedConfiguration
:被增强器增强过的配置类,都会自动的让实现此接口(实际是个BeanFactoryAware
)接口SpringNamingPolicy
:使用 CGLIB 生成字节码类名名称生成策略 -> 名称中会有BySpringCGLIB
字样BeanFactoryAwareMethodInterceptor
:CGLIB 代理对象拦截器。作用:拦截代理类的setBeanFactory()
方法,给对应属性赋值BeanMethodInterceptor
:CGLIB 代理对象拦截器。作用:拦截所有 @Bean 方法的执行,以支持可以通过直接调用 @Bean 方法来管理依赖关系(当然也支持FactoryBean
模式)
配置类解析流程图
**配置类的解析均是交由ConfigurationClassPostProcessor
来引导**。在 Spring Framework 里(非 Spring Boot)里,它是BeanDefinitionRegistryPostProcessor
处理器的**唯一**实现类,用于引导处理@Configuration
配置类。解析入口是postProcessBeanDefinitionRegistry()
方法,实际处理委托给了processConfigBeanDefinitions()
方法。
配置类增强流程图
如果一个配置类是 Full 模式,那么它就需要被 CGLIB 字节码提升。增强动作委托给enhanceConfigurationClasses(beanFactory)
去完成。
以上是引导/调度的流程图,下面对字节码增强、实际拦截实现流程进行细分描述。
生成增强子类字节码流程图
针对于 Full 模式配置类的字节码生成,委托给ConfigurationClassEnhancer
增强器去完成,最终得到一个 CGLIB 提升过的子类 Class 字节码对象。
字节码实际是由 Enhancer 生成,就不用再深入了,那属于 CGLIB(甚至 ASM)的范畴,很容易头晕,也并无必要。
拦截器执行流程图
拦截器是完成增强实际逻辑的核心部件,因此它的执行流程需要引起重视。一共有两个“有用”的拦截器,分别画出。
BeanFactoryAwareMethodInterceptor 拦截流程图
拦截setBeanFactory()
方法的执行
BeanMethodInterceptor 拦截流程图
拦截@Bean
方法的执行
总结
本文作为公众号首个专栏 Spring 配置类的总结篇,主要是对核心处理流程画图阐述,适合需要快速理解的白嫖党,毕竟面试最喜欢问的就是让你说说执行流程之类的,因此实用性还是蛮高的,以后的专栏均会仿造此套路来玩。
关于 Spring 配置类这个专栏到这就全部结束了,在此也多谢各位在这期间给我的反馈,让我确定以及肯定了这么坚持下去是有意义的,是被支持的,是能够帮助到同仁们的。我公众号定位为专栏式学习,拒绝浅尝遏止,诚邀你的关注,一起进步。
Tips:有小伙伴私信我说有没有入门级别的?答案是没有的。主要是觉得入门级文章网上太多了,趋同性很强,所以我这一般会篇进阶,有点工作经验/基础再看效果更佳
---------
关注 A 哥
Author | A 哥(YourBatman)
-------- | -----
个人站点 | www.yourbatman.cn
E-mail | yourbatman@qq.com
微 信 | fsx641385712
公众号 | BAT的乌托邦(ID:BAT-utopia)
知识星球 | BAT的乌托邦
每日文章推荐 | 每日文章推荐
版权声明: 本文为 InfoQ 作者【YourBatman】的原创文章。
原文链接:【http://xie.infoq.cn/article/a93585f5e81048ede91a096b7】。文章转载请联系作者。
评论