目录
总览:Ioc是Spring的一切的基础,而BeanFactory又是Ioc的基础。
1、BeanFactory的实现逻辑
2、ApplicationContext与BeanFactory的关系
3、SpringMVC与ApplicationContext的关系
4、Spring Boot与ApplicationContext的关系
他们关系的流程图可以参见图:https://www.processon.com/view/link/5bfe805fe4b018141e855cbf
一、BeanFactory
BeanFactory主要的实现的接口:
BeanDefinitionRegistry:BeanDefinition的注册容器
DefaultSingletonBeanRegistry:Singleton Bean的注册容器
1)、SimpleAliasRegistry:单利Bean的别名容器注册
2)、SingletonBeanRegistry:单利Bean的注册容器
1)、注册BeanDefinition
BeanFactory需要先将BeanDefinition加载到BeanDefinitionRegistry,再在每个Bean调用getBean方法时根据BeanDefinition初始化Bean放入缓存中。而加载BeanDefinition有很多种方式:
1、XmlBeanFactory
XmlBeanFactory使用Resource加载的Spring xml配置,再将流转换为Document,再使用Parse解析再加载到
2、@Import
3、ImportAware
4、@ComponentScan
后面集中方式都会在ApplicationContext中按照不同的加载方式拿到后,调用loadBeanDefinition加入BeanDefinitionRegistry
2)、getBean
执行整个Bean的生命周期(可以参见Spring-Bean的作用域和生命周期),循环依赖的问题(单利Bean)等。当初始化完成后则注册到SimpleAliasRegistry和SingletonBeanRegistry中。
二、ApplicationContext
ClassPathXMLApplicationContext
AnnotationConfigWebApplicationContext
AnnotationConfigApplicationContext
AnnotationConfigServletWebServerApplicationContext
AnnotationConfigReactiveWebServerApplicationContext
不论哪种都是集成自核心AbstractApplicationContext的refresh模板方法,是模板方法自然就会在特定的时候会调用自己重新的某些步骤。其中与BeanFactory相关的是refresh以下步骤:
obtainFreshBeanFactory:初始化BeanFactory,如果是Xml类型的BeanFactory则会有XMLBeanFactory相关的处理
invokeBeanFactoryPostProcessors: 处理@ComponentScan、ImportAware等方式的BeanDefinition,注册到容器BeanFactory的BeanDefinitionRegistry中
finishBeanFactoryInitialization: 将所有非懒加载的单利Bean都初始化:调用getBean方法
三、Spring MVC
传统的Spring MVC方式启动时,启动的是WebApplicationContext的子类。有三种启动方式:
ContextLoadServlet:使用ContextConfigLocation配置
ContextLoaderListener:Tomcat容器等启动时,会触发监听,Spring容器去注册该监听
ContextLoaderPlugin:使用插件方式启动
不论使用哪种方式,都会触发ContextLoader#initWebApplicationContext方法,则会在内部调用configureAndRefreshWebApplicationContext方法,间接得调用AbstractApplicationContext的refresh方法。
四、Spring Boot
Spring Boot项目启动会调用在main方法中调用
SpringApplication#run方法,内部会调用createApplicationContext方法,会根据调用run方法是传入的
webApplicationType类型判断初始化的ApplicationContext类型:
AnnotationConfigApplicationContext
AnnotationConfigServletWebServerApplicationContext
AnnotationConfigReactiveWebServerApplicationContext
但是不论哪种方式都会调用AbstractApplicationContext的refresh方法,去完成Spring容器的初始化。