首先通过new AnnotationConfigApplicationContext(ExtConfig.class);传入一个配置类开始,进入IOC容器创建的第一步,进入refresh()方法,下面主要介绍这个方法中的内容。

如何用runc创建容器 创建ioc容器_初始化

如何用runc创建容器 创建ioc容器_spring_02

1. prepareRefresh();方法,刷新前的预处理

如何用runc创建容器 创建ioc容器_如何用runc创建容器_03

1.initPropertySources();初始化一些属性设置,这个是一个空方法,留给子类重写,通过它子类可以自定义个性化属性设置

2.getEnvironment().validateRequiredProperties();进行属相校验,检验属性是否合法

3.this.earlyApplicationEvents = new LinkedHashSet<>();创建一个集合保存容器中的早期事件

2.obtainFreshBeanFactory();获取beanFactory

如何用runc创建容器 创建ioc容器_IOC容器_04

1.refreshBeanFactory();刷新bean工厂,其中通过GenericApplicationContext的无参构造器创建一个beanFactory,并为BeanFactory设置一个序列化标识

2.getBeanFactory();获得banFactory,返回刚才通过GenericApplicationContext无参构造器创建的beanFactory

3.将创建的beanFactory直接返回,类型为DefaultListableBeanFactory

3.prepareBeanFactory(beanFactory);beanFactory的预处理设置,在其中对beanFactory进行设置

1.设置beanFactory的类加载器,支持的表达式解析器等等......

如何用runc创建容器 创建ioc容器_IOC容器_05

2.添加一个BeanPostProcessor(ApplicationContextAwareProcessor) 

如何用runc创建容器 创建ioc容器_spring_06

3.设置忽略的自动装配接口

如何用runc创建容器 创建ioc容器_如何用runc创建容器_07

 4.注册可以解析的自动装配组件,即可以通过@Autowired注入的组件

如何用runc创建容器 创建ioc容器_流程解析_08

5. 添加BeanPostPeocessor(ApplicationListenerDetector)

如何用runc创建容器 创建ioc容器_IOC容器_09

6. 添加编译时的Aspect支持

7.给BeanFactory中添加一些能用的组件,例如:environment【ConfigurableEnvironment】,systemProperties【Map<String, Object>】,systemEnvironment【Map<String, Object>】

如何用runc创建容器 创建ioc容器_流程解析_10

4.postProcessBeanFactory(beanFactory);在beanFactory后进行后置处理工作

1.进入为空方法,子类可以重写这个方法,在beanFactory创建并预准备完成后对其进行设置

5.invokeBeanFactoryPostProcessors(beanFactory);执行beanFactoryPostProcessor

beanFactoryPostProcessor是beanFactory的后置处理器,是在beanFactory标准初始化之后执行,存在两个接口:BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

如何用runc创建容器 创建ioc容器_IOC容器_11

如何用runc创建容器 创建ioc容器_如何用runc创建容器_12

 1.获取所有的BeanDefinitionRegistryPostProcessor

如何用runc创建容器 创建ioc容器_如何用runc创建容器_13

2.先执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,调用他们的postProcessor.postProcessBeanDefinitionRegistry(registry);方法 

3.在执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor,调用他们的postProcessor.postProcessBeanDefinitionRegistry(registry);方法

4.最后执行没有实现任何优先级或接口的BeanDefinitionRegistryPostProcessor

5.获取所有的BeanFactoryPostProcessor

如何用runc创建容器 创建ioc容器_IOC容器_14

6.先执行实现了PriorityOrdered接口的BeanFactoryPostProcessor,调用他们的postProcessor.postProcessBeanFactory(beanFactory);方法

7.在执行实现了Ordered接口的BeanFactoryPostProcessor,调用他们的postProcessor.postProcessBeanFactory(beanFactory);方法

8.最后执行没有实现任何优先级或接口的BeanFactoryPostProcessor

注: BeanFactoryPostProcessor接口是BeanDefinitionRegistryPostProcessor的父接口,BeanFactoryPostProcessor是在beanFactory标准初始化之后(即所有的bean定义已经加载了,但并没有创建bean实例)执行,而BeanDefinitionRegistryPostProcessor是在所有bean定义信息将要被加载,bean实例还未创建,优先于BeanFactoryPostProcessor执行。

6.registerBeanPostProcessors(beanFactory);注册BeanPostProcessors即bean的后置处理器,拦截bean的创建过程

他的下面还有很多接口:DestructionAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor,SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor【记录在internalPostProcessors中】不同的beanPostProcessor在bean的创建前后执行时机是不一样的

1.获取所有的beanPostProcessor

如何用runc创建容器 创建ioc容器_spring_15

2.先注册PriorityOrdered接口优先级的后置处理器,将每一个beanPostProcessor加入到BeanFactory中

如何用runc创建容器 创建ioc容器_流程解析_16

3.在注册实现了Ordered接口的

4.最后注册没有实现任何接口的BeanPostProcessor

5.最后注册MergedBeanDefinitionPostProcessor类型的后置处理器

6.最终还注册一个ApplicationListenerDetector探听器,检查在bean创建完成后是否是ApplicationListener,如果是将bean放在容器中保存起来 

如何用runc创建容器 创建ioc容器_初始化_17

7.initMessageSource();初始化MessageSource组件(做国际化,消息绑定,消息解析),一般用在取出国际化配置文件中的某个key值,能按照区域信息获取 

1.获得beanFactory

如何用runc创建容器 创建ioc容器_流程解析_18

2.判断容器中是否有id为messageSource的组件存在,如果有就获得到messageSource赋值给this.messageSource,如果没有就创建一个DelegatingMessageSource

3.将创建好的messageSource注入到beanFactory中,以后获取国际化配置文件值可以自动注入messageSource,调用getMessage()方法

8.initApplicationEventMulticaster();初始化事件派发器 

1.获得beanFactory

如何用runc创建容器 创建ioc容器_初始化_19

2.从beanFactory中获取applicationEventMulticaster【ApplicationEventMulticaster】组件,即自己配置的事件派发器

3.如果自己没有配置,就创建一个SimpleApplicationEventMulticaster

4.将ApplicationEventMulticaster加入到beanFactory中,以后其他组件就可以自动注入

9.onRefresh();留给子容器(子类) ,这也是一个空方法,子类重写,在容器刷新时可以自定义逻辑

10.registerListeners();将所有监听器注册到容器中

1.从容器中拿到所有的ApplicationListener组件

如何用runc创建容器 创建ioc容器_IOC容器_20

2.将每个监听器添加到事件派发器中

3.派发前面步骤产生的事件

11.finishBeanFactoryInitialization(beanFactory);初始化剩下的所有的单实例bean

1.beanFactory.preInstantiateSingletons();

如何用runc创建容器 创建ioc容器_初始化_21

2.获取容器中的所有bean,依次进行初始化创建对象

如何用runc创建容器 创建ioc容器_IOC容器_22

3.判断bean是否是抽象的,单实例的,懒加载的

4.判断是否是FactoryBean,即判断是否是FactoryBean接口的,如果是,就通过其自身的getObject()创建bean

5.如果不是,就通过getBean(beanName);创建对象

6.getBean(beanName);会调用doGetBean(name, null, null, false);

如何用runc创建容器 创建ioc容器_流程解析_23

7. 先获取缓存中的单实例bean,如果能获取到,说明bean之前创建过了,即创建过得单实例bean都会被缓存起来

如何用runc创建容器 创建ioc容器_IOC容器_24

8.缓存中不存在,就开始bean的创建流程

9.标记当前bean已经被创建了   markBeanAsCreated(beanName);,防止出现多线程创建bean,单实例就不成立了

如何用runc创建容器 创建ioc容器_初始化_25

 10.获取bean的定义信息

如何用runc创建容器 创建ioc容器_流程解析_26

11. 获取当前bean所依赖的其他bean,如果有依赖的bean,就通过getBean(dep);先将依赖的bean创建出来

如何用runc创建容器 创建ioc容器_流程解析_27

12.调用createBean(beanName, mbd, args);创建bean

如何用runc创建容器 创建ioc容器_初始化_28

13.调用Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,让beanPostProcessor先拦截返回代理对象,提前执行InstantiationAwareBeanPostProcessors类型的后置处理器,执行postProcessorsBeforeInstantiation()方法,如果有返回值在出发postProcessAfterInitialization()

如何用runc创建容器 创建ioc容器_流程解析_29

如何用runc创建容器 创建ioc容器_初始化_30

 14.若果没有返回代理对象就调用doCreateBean(beanName, mbdToUse, args);创建对象

如何用runc创建容器 创建ioc容器_初始化_31

15.通过createBeanInstance(beanName, mbd, args);创建bean实例,通过工厂方法或对象的构造方法

如何用runc创建容器 创建ioc容器_初始化_32

 16.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用MergedBeanDefinitionPostProcessor类型的后置处理器的postProcessMergedBeanDefinition()方法

如何用runc创建容器 创建ioc容器_spring_33

如何用runc创建容器 创建ioc容器_spring_34

17.通过populateBean(beanName, mbd, instanceWrapper);对bean的属性赋值

如何用runc创建容器 创建ioc容器_IOC容器_35

18.在属性赋值中,拿到InstantiationAwareBeanPostProcessor类型的后置处理器,调用postProcessAfterInstantiation()方法

如何用runc创建容器 创建ioc容器_如何用runc创建容器_36

19.再次拿到InstantiationAwareBeanPostProcessor类型的后置处理器,调用postProcessPropertyValues()方法

如何用runc创建容器 创建ioc容器_流程解析_37

20.applyPropertyValues(beanName, mbd, bw, pvs);为属性赋值

如何用runc创建容器 创建ioc容器_spring_38

21.赋值完成后,通过initializeBean(beanName, exposedObject, mbd);初始化bean

22.在初始化中,invokeAwareMethods(beanName, bean);执行aware接口方法

如何用runc创建容器 创建ioc容器_spring_39

判断是否是BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口的实例

如何用runc创建容器 创建ioc容器_如何用runc创建容器_40

23.执行aware接口后,applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);调用所有后置处理器postProcessBeforeInitialization()方法

如何用runc创建容器 创建ioc容器_如何用runc创建容器_41

24.invokeInitMethods(beanName, wrappedBean, mbd);执行初始化方法

如何用runc创建容器 创建ioc容器_初始化_42

注:bean的初始化方法可以有很多种写法,例如:实现InitializingBean,DisposableBean两个接口,实现afterPropertiesSet()及destroy()方法,还可以通过@Bean(initMethod="init",destroyMethod="destory")指定初始化及销毁方法

25.判断是否是InitializingBean类型的bean,如果是就会调用相应的初始化方法

如何用runc创建容器 创建ioc容器_流程解析_43

26.是否自定义初始化方法

如何用runc创建容器 创建ioc容器_spring_44

27.初始化完成后,applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);调用所有后置处理器的postProcessAfterInitialization()方法

如何用runc创建容器 创建ioc容器_初始化_45

28.通过22-28完后,bean就初始化好了,registerDisposableBeanIfNecessary(beanName, bean, mbd);注册bean的销毁方法

如何用runc创建容器 创建ioc容器_如何用runc创建容器_46

29.addSingleton(beanName, singletonObject);将已创建的bean添加到缓存中

如何用runc创建容器 创建ioc容器_初始化_47

30.所有bean都利用getBean()创建完成了,检查所有的bean是否是SmartInitializingSingleton接口的,如果是就调用afterSingletonsInstantiated()方法

如何用runc创建容器 创建ioc容器_如何用runc创建容器_48

12.finishRefresh();完成bean工厂的初始化工作,IOC就创建完成

1.initLifecycleProcessor();初始化和生命周期有关的后置处理器,允许写一个LifecycleProcessor的实现类,可以再BeanFactory刷新完成后调用onRefresh(),关闭时调用onClose();默认在容器中找LifecycleProcessor组件,如果没有就默认使用new DefaultLifecycleProcessor(),并加入到容器中

如何用runc创建容器 创建ioc容器_IOC容器_49

2.getLifecycleProcessor().onRefresh();获得前面的生命周期处理器(监听beanFactory生命周期),调用onRefresh()方法

3.publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件

13.总结

到此Spring IOC容器就初始化完成啦

1.spring容器在启动时,会保存所有bean的定义信息,使用xml定义bean信息   <bean></bean>和使用注解注册bean  @Service @Component  @Bean........

2.当容器中已经有bean的定义信息时,在合适的时机就会创建bean

时机一:在用到bean时,利用getBean()创建bean,创建好以后保存在容器中

时机二:统一创建剩下的单实例bean,即第11大步

3.后置处理器(重点,技术核心)

每一个bean在创建完成以后,都会使用各种后置处理器,增强bean功能,例如:自动注入的后置处理器AutowiredAnnotationBeanPostProcessor处理自动注入,AnnotationAwareAspectJAutoProxyCreator给bean创建代理对象,实现AOP.等等.........

4.事件驱动模型:ApplicationListener事件监听,通过ApplicationEventMulticaster进行事件派发