IOC容器的加载过程-Bean的生命周期(粗略版)

核心模块部分截图:

 

 IOC 源码加载过程:

1. new AnnotationConfigApplicationContext():

 

 

 

 再看:AnnotationConfigApplicationContext()的无参构造方法:(因为上面有参构造方法调用了 this()):

 

 

 这些后置处理器最终注册成为一个RootBeanDefinition,点进注册内置的后置处理器方法即可看到,这里不展开。

 

 可以看到该类实现了BeanFactoryPostProcessor,前一篇文章中我也提到BeanFactoryPostProcessor是Spring的扩展点,可以集成第三方框架、扫描配置类,注解等,功能强大。在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。

 

 这里有一个扫描器,上篇文章也提到过了, BeanDefinitionScanner,主要是一个类路径下的bean定义扫描器。里面有个很重要的方法,doScan,传参可以接收包的全路径。

 

 总结上面三个步骤:(调用this()无参构造进行初始化)

1. new Bean工厂;

2. 定义出Bean定义读取器;

3. 定义出bean扫描器;

注册配置类

见上图第一张源码图,在执行完成this()方法之后,就开始注册我们的配置类了。其本质是通过读取器读取配置类,最后注册成为一个Bean定义。该Bean定义会放入beanDefinitionMap中。

 

IOC容器刷新接口 - refresh() 

然后见第一张源码图,就是调用最重要的方法,refresh()方法了。本次主要看下下面两个方法:

invokeBeanFactoryPostProcessors:调用bean工厂的后置处理器,解析配置类,将配置类注册成Bean定义

finishBeanFactoryInitialization():实例化剩余的单例Bean,将Bean定义注册成为Bean实例。期间会调用getBean();

 

 单例生产标准:

 

 

getBean()调用方法的一些过程:判断是否符合生产标准;判断是不是FactoryBean,如果是FacotyBean,最终注册进来的是一个原型的Bean,&Car。比如Mybatis就用到了该种类似的代理模式,spring整合mybatis采用的是MapperFactoryBean,返回的是getObject所返回的Bean; 

如果后续调用getBean() 方法,先从一级缓存中拿,没有拿到就调用createBean。这里就会调用我们的第一个后置处理器,BeanPostProcessor,如InstantiationAwareBeanPostProcessor。BeanPostProcessor可以阻止Bean的创建。它可以由我们自己去创建,一般不会。 

然后就是后面说的doCreateBean()方法的调用了。doCreateBean之前会标记Bean正在创建,可以解决循环依赖问题。

初始化Bean主要分为三步吧。中间会执行很多的BeanPostProcessor。

1. 通过反射或者FacytoryBean创建Bean对象,

2. Bean的初始化,主要就是:

属性赋值;

调用Bean初始化的三种方式,包括InitializingBean、@PostConstructor 、initMethod。

调用一系列的aware方法

BeanNameAware
BeanClassLoaderAware
BeanFactoryAware

ApplicationContextAwareProcessor相关的aware方法。该接口有一个很重要的方法,invokeAwareInterfaces

3. 将bean放入到一级缓存当中,也就是Map对象中。

(小插曲:基于XML的去解析Bean定义是在AbstractRefreshableApplicationContext 的 refreshBeanFactory()方法)

End!

 

posted @ 2022-11-17 17:49  君莫笑我十年游  阅读(193)  评论(0编辑  收藏  举报