Spring后置处理器源码,彻底理解Spring核心

120 篇文章 2 订阅
79 篇文章 0 订阅

简单对上篇做个总结:

首先咱们一起写了一个HelloWorld版本的Spring。因为Spring核心是控制反转,就是Bean对象都交给Spring来管理。开发者使用时只需要获取即可。在使用时分为两步:第一步,通过注解配置创建Spring上下文容器;第二步,从中获取需要的Bean来使用。

那讲道理就先把这两步需要的框架构造出来,于是先有了下面的架子:

然后咱们要把这个架子填充血肉,达到真的可以通过注解来使用Spring,进行依赖注入的目标。那首先要把使用到的注解定义出来:

根据这些注解和定义好的框架来实现功能,这是一个有工作经验的开发人员都可以做到的事情。最终的代码为了让大家便于和Spring源码结合,我把名称稍微调整了一下,名称和Spring源码中一致,作用也一致:

spring创建Bean的重点步骤这里面体现了:

1、根据class生成Bean定义

2、根据Bean进行实例化

3、将实例的Bean属性进行填充(autowired的属性实例化)

4、完成Bean对象的创建

实际上spring在将Bean进行实例化到生成Bean对象之前还进行了很多的处理,比如说Bean初始化和Bean增强。AOP和Bean后置处理器有着密切的关系。今天就来重点说一下这部分。

本文的所有代码文字在 https://github.com/xiexiaojing/yuna 里可以找到。

Bean初始化

Spring初始化Bean有三种方式,原理是一样的,分别是:

1、实现InitializingBean接口

2、使用 @PostConstruct 注解

3、或者指定 init-method

<bean   id="testInitializingBean"  class="com.TestInitializingBean"  init-method="testInit"> </bean>

他们同时存在时是有先后顺序的:

执行顺序:

构造器Constructor >

@PostConstruct >

InitializingBean >

init-method

由于上节大量实现了注解方式,三种初始化方式原理大同小异,本篇就手撕 InitializingBean 方式的代码:

先定义一个 InitializingBean 接口,直接从spring-beans的源码把接口定义复制过来即可:


然后找个使用场景,比如Bean实例化后要从远程获取值:

实现也很简单,创建Bean之后加上一个判断+调用:


来看一下效果:

以上就是Spring初始化过程的实现。

Bean的后置处理器

Spring中有两种后置处理器,分别为BeanFactoryPostProcessor和BeanPostProcessor。前者叫bean工厂后置处理器,后者叫bean后置处理器。现在咱们都在讲 Bean ,还没讲到 BeanFactory ,这里不做过多介绍。

后置处理器的作用好像是做木工。先把大体木雕的轮廓做出来,下一步还要进行微调及上色,就是再加工。Spring-AOP 就是通过后置处理器实现的。

那Bean后置处理器的执行时机是什么呢?看了接口定义就明白了。同样,咱们把Spring后置处理器的接口直接复制过来:

这里面有两个方法,一个方法叫:

初始化前,后置处理

一个方法叫:

初始化后,后置处理

咱们就按照方法定义来实现:

注意这里有个 postProcessorList 是我刚刚新定义的,因为Spring不只有一个后置处理器,来提供足够的扩展性:

那Spring什么时候把后置处理器放到这个list里面的呢?扫描的时候放的,举个具体的后置处理器例子:

因为要被扫描到,那一定要是个Component。打印的那两句歌词,我经常用,所以说明一下出处:在《深入理解MQ生产端的底层通信过程-理解channel》里我有把歌曲原唱放上。大学的时候爱听,现在再听已经不觉得好听了。大概是发现结婚这十几年,老公得到了任性的爱情,自己却是那个万般包容的人心里不爽。哈哈哈,开个玩笑,像咱这种普通人,最终在一起的人都是相互包容,相互成就的。

放松了一下,回归正题,扫描后置处理器:

因为后置处理器有严格定义,内部不能绑定Bean,不需要执行初始化,所以可以直接实例化。

运行结果:

这里后置处理器的两个方法各运行了两次,是因为创建了两个Bean:

当然,我们可以指定后置处理器的生效条件,可以不对所有的Bean生效。

这里简单引入一下 AOP ,我也不卖关子了。AOP是通过一个叫 

AnnotationAwareAspectJAutoProxyCreator

的后置处理器实现的。里面的很多实现就来判断自己可以代理哪些Bean的。

 

总结

再来总结一下spring创建Bean的重点步骤:

1、根据class生成Bean定义

2、根据Bean进行实例化

3、将实例的Bean属性进行填充

4、初始化Bean

5、Bean后置处理

6、完成Bean对象的创建

如果我把代码再规整一下,用Spring代码同样的方法命名,大家会发现与Spring源码很多地方已经很接近的。相信对Spring源码的理解是有帮助的。

“做程序员,圈子和学习最重要”因为有有了圈子可以让你少走弯路,扩宽人脉,扩展思路,学习他人的一些经验及学习方法!同时在这分享一下是一直以来整理的Java后端进阶笔记文档和学习资料免费分享给大家!需要资料的朋友私信我扣【06】
 

来源:手撕Spring后置处理器源码,彻底理解Spring核心

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值