BeanFactory创建Bean步骤源码解析

BeanFactory是spring的核心,我们都知道可以从BeanFactory中获取到指定的bean(通过名字或者Class),同时我们也会很好奇,bean是怎么被加载到BeanFactory里面的呢?Spring又给我们留了哪些后门能够插手这个加载过程呢?带着这些疑问,我们通过源码一步一步来分析。

首先我们看一下BeanFactory的一个简单的UML图,并对其中几个进行简单分析,这样有助于理解

BeanFactory的UML图

1、BeanFactory

这是最顶层的接口,它定义了工厂类最核心的方法(可以想想工厂模式,定义一个获取产品的接口)

BeanFactory中定义的接口

2、HierarchicalBeanFactory

BeanFactory的直接子接口,表示Bean是有继承关系的,也就是Bean可能有父Bean

HierarchicalBeanFactory中定义的接口

3、ListableBeanFactory

BeanFactory的又一个直接子接口,表示这些bean可列表化(可以简单理解为增加了一些接口,可以根据不同的条件来查询bean或者bean的信息)

ListableBeanFactory中定义的方法

4、AutowireCapableBeanFactory

BeanFactory的直接子接口,定义bean的自动装配规则(bean创建,属性设置,依赖注入,各种拦截器等)。

AutowireCapableBeanFactory中定义的方法

通过分析这4个接口,我们能够猜到BeanFactory创建bean真正的类应该是AutowireCapableBeanFactory的子类。

没错,Spring加载Bean的位置确实是AutowireCapableBeanFactory的直接子类AbstractAutowireCapableBeanFactory。接下来我们一步一步来分析AbstractAutowireCapableBeanFactory的createBean方法。

5、AbstractAutowireCapableBeanFactory

实现了bean的创建。现在我们来分析一下他的创建的过程。

createBean方法

可以看出此方法并没有真正创建Bean,我们接着往下看createBean

createBean

从源码中可以看出此方法定义了bean创建的步骤:

第一步:先确保bean的Class能被解析

第二步:在实例化bean之前,给了一个钩子(InstantiationAwareBeanPostProcessor),允许我们在钩子中直接返回一个我们创建的bean或者代理,这样,Spring就不会继续往下执行,也就不会在创建bean

第三步:调用doCreateBean,进行bean的实例化,以及后续加工处理。

接着我们继续看doCreateBean方法:

doCreateBean方法
doCreateBean方法
doCreateBean方法

解释一下主要的创建流程:

第一步:根据情况实例化bean

a:如果Bean配置了FactoryMethod,那么使用FactoryMethod进行实例化

b:如果Bean在次之前已经解析出了实例化的构造函数或者FactoryMethod,那么根据情况使用构造函数或者FactoryMethod进行实例化

c:如果能够确定是否指定了构造函数,那么使用确定的构造函数进行实例化

d:如果都没有,那么直接使用默认构造函数(即无参构造函数)进行实例化

(真正实例化bean使用了策略模式,会根据bean的信息选择不同的实例化策略,后面详细介绍)

根据不同的情况实例化bean

第二步:Spring又提供了一个钩子(MergedBeanDefinitionPostProcessor),这是用于合并bean定义的后处理器。这么说肯定一脸懵,完全不知道有什么用。

举个例子:我们都知道Bean中可以使用@Autowired注解来配置另外一个Bean,Spring解析Autowired注解的时机就是此时此刻,以便下一步进行属性填充(或者说注入)

(MergedBeanDefinitionPostProcessor这个接口对@Autowired和@Value的支持起到了至关重要的作用,当某个bean在实例化后就会调到所有的实现了MergedBeanDefinitionPostProcessor接口的实例。)

例如:

CommonAnnotationBeanPostProcessor这个处理器用来解析类中使用的@Resource注解AutowiredAnnotationBeanPostProcessor这个处理器用来解析类中使用的@Autowired注解

(注意这些处理器只是用来解析类使用的这些注解,并不会直接注入对应的值)

钩子,应用MergedBeanDefinitionPostProcessors

第三步:填充bean的属性、依赖等

这个过程也涉及很多流程,但是最终就是Spring会在这个步骤中将bean对应的依赖进行设置

第四步:对bean进行初始化

初始化我们不要和前面的实例化混淆了。初始化指的是当我们的bean实例化之后,有可能需要做一些初始化工作(比如:预加载数据)。接下来我们分析一下Spring对初始化做了哪些操作。

bean初始化过程

a、调用三类Bean的对应方法,他们分别是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,我们分别可以获得bean的名字、bean的Class加载器、bean的创建工厂。其中BeanFactoryAware是我们常用的,我们的BeanUtil通过实现它,然后在其他服务中可以通过BeanUtil获取BeanFactory,从而在程序运行中获取其中的Bean

Spring主动调用的三类Bean

b、初始化前的钩子,即:调用BeanPostProcessor的postProcessBeforeInitialization方法

调用BeanPostProcessor的postProcessBeforeInitialization

c、调用Bean的初始化方法

此处我们要注意:

如果Bean实现了InitializingBean,那么Spring就会在此刻调用它的afterPropertiesSet()方法

如果Bean指定了初始化方法,那么Spring会调用这个方法

init方法

d、初始化后的钩子,即:调用BeanPostProcessor的postProcessAfterInitialization方法

调用BeanPostProcessor的postProcessAfterInitialization

至此,Spring创建Bean的流程基本结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容