Spring IOC(3)----bean实例化源码流程
前面一节说到invokeBeanFactoryPostProcessors方法的调用来注册bean定义,这次来看看finishBeanFactoryInitialization这个方法实例化非懒加载的单例bean。
1.refresh方法中调用invokeBeanFactoryPostProcessors方法实例化非懒加载的bean。
2.从getBean到doGetBean先尝试从单例缓存池里面获取,如果获取不到则判断当前bean是否正在被创建,如果在被创建则等待锁,然后从尝试从早期对象缓存中获取,如果允许更早的引用就去更早的singletonFactories缓存中获取。这就spring IOC的三级缓存。
3.没有获取到,就去bean定义中拿出对应的bean定义,准备创建对象,如果是,然后根据是否是单例对象,进入不同的创建流程。
4.再次尝试从单例缓存中获取,获取到了直接返回,获取不到则回调上面一步的createBean方法
5.createBean中有一个实例化前的解析方法(resolveBeforeInstantiation),如果解析出对象直接返回,但是实际上这里解析不出来对象。注释虽然说返回代理对象,但是这个时候实际的对象都还没有创建,根本不知道应该代理谁。所以这里只是去解析了切面信息缓存起来,供后面创建代理对象的时候使用。后续分析Spring Aop的时候详解此方法。
6.然后就是重头戏,创建对象了。AbstractAutowireCapableBeanFactory#createBeanInstance方法。会通过几种方式创建bean,比如我们@bean注解标注的方法;@autowire注入的方式,通过构造方法创建;直接调用无参构造来创建。
7.此时我们的对象就创建在了一个包装对象里面,但是这个时候对象的还没有赋值。这就是所谓早期对象,也就是还没有初始化的对象。
8.这个时候如果我们实现了MergedBeanDefinitionPostProcessor这个处理器,就会这个时候进行调用了,合并到系统的一个bean定义中去,后续使用。然后进行一些判断是否允许将这个早期对象暴露出去。如果允许则会将此早期对象加入到上面说到的对应缓存中去。
9.然后执行populateBean这个方法对属性进行赋值。先执行Autowire的两种name和Type
10.然后执行我们自己实现的InstantiationAwareBeanPostProcessor这个接口的postProcessProperties和postProcessPropertyValues方法
11.赋值就执行完毕,接下来就是执行initializeBean方法中调用Aware接口的三个实现,以及BeanPostProcessor接口的before方法,初始化方法比如这个@PostConstruct标注的方法,BeanPostProcessor接口的after方法。
12.最后添加到缓存中去
大致流程图:
Spring IOC(1-3)的大致流程图可以拼出来一个完整的从前期准备到注册bean定义,再到实例的流程,完整的流程如下: