1、ClassPathXmlApplicationContext
创建spring以用程序上下文 调用构造方法
1、调用父类的构造方法创建PathMathingResourcePatternReslover 解析配置文件
2、设置配置文件路径到当前应用程序中
3、开始进入容器的创建和刷新环节 refresh();prepareRefresh 容器刷新前的准备工作;
设置容器的启动时间
设置活跃状态为true;
设置关闭状态为false;
initPropertySources();
获取Environment对象,并加载当前系统的属性值到Environment对象中
准备监听器和事件的集合对象,默认为空集合;
2、obtainFreshBeanFactory 创建容器,并且完成配置文件的加载
1、createBeanFactory; 创建一个对象,DefaultListableBeanFactory
2、beanFactory.setSerializationId;设置beanFactory的id;
3、customizeBeanFactory:定制化beanFactory,有两个属性值
1、是否允许beanDefinition被覆盖
2、是否允许循环依赖;
4、loadBeanDefinitions;加载配置文件,读取bean的定义信息;
1、beanDefinitionReader-》XmlBeanDefinitionReader 读取beanDefinition,xml的属性信息定义在xsd约束文件里;schemas
2、设置当前系统的环境变量;environment
3、设置资源加载器;
4、设置实体处理器;解析配置文件的处理器;构造方法设置了schemas的地址;
5、initDeifinitionReader,初始化当前reader对象,此处设置配置文件是否要进行验证
6、loadBeanDefinition(beanDefinitionReader);
1、获取当前配置文件的路径;
2、xmlBeanDefinitionReder.loadDefinitions(String[]);传入的配置文件地址
1、循环处理配置文件;
7、doLoadBeanDefinitions (inputSource,encodeREsource.getResource())实际干活的方法,将配置文件解析成文档对象,方便通过父子节点的方式获取对应的标签元素
1、doLoadDocument()将读取的配置文件的字符串读成一个document对象;解析完成之后包含一些节点信息
2、registerBeanDefinitions(doc,resource);根据文档的读取信息,封装成beanDefinitions; 解析标签元素且完成注册功能;
1、BeanDefinitionMap:key:beanName value:BeanDefinition
2、BeanDefinitionNames:存放beanDefinition的名称的集合
8、doRegisterBeanDefinition(Element root) 实际完成注册操作
1、createDelegate();
2、parseBeanDefinition 解析beanDefinition
1、遍历外层标签中 子标签,然后开始判断用什么样的方式进行解析操作
2、默认的命名空间,有默认的标签。bean、import、alias等;使用默认的方式进行解析;parseDefaultElement
3、使用额外的方式进行解析;parseCustomElement;
1、跟进当前标签的命名空间字符串查找对应的hanlder处理类;spirng.handlers
2、通过不同的handler对象去解析不同的标签元素 handler.parse不同的标签有不同的处理类,具体的处理逻辑可能不同,但是最终都会获取到完成的beanDefinition
3、创建genericBeanDefinitions
4、将解析完成的BeanDefinition对象注册到容器的BeanDefinitionMap和BeanDefinitionNames集合中
3、prepareBeanFactory给容器对象完成属性的赋值操作
1、设置bean加载器
2、设置ExpresssionResolver spel表达式解析器
3、addPropertytEditorRegister 属性编辑器 参数对应解析类;
4、beanPostProcessors (new ApplicationContextAwareProcessor(this))集合 bpp在bean实例化之后进行相关的操作,ApplicationContextAwareProcessor完成某些aware对象的注入
5、ignoredDependenceInterfaces 忽略依赖的接口;第四步已经处理的进行忽略;
6、registerResolvableDependencies 设置几个自动装配的特殊规则,在进行ioc初始化时如果有多个实现,那么就是用指定的对象进行注入;例如@Primary
7、singletonObjct
4、postProcessBeanFactory 默认没有实现,留给子类进行实现操作
扩展时继承这个类,重写这个方法即可;
5、invokeBeanFactoryPostProcessor 执行bfpp接口中的方法
自定义的话可以调用具体的add方法或者在xml里进行bean的定义;
BeanDefinitionRegistryPostProcessor 是BeanFactoryPostProcesser的子类;
1、可以自用扩展,修改beanFactory中的相关信息,但是使用最多的是对BeanDefintion的修改操作
1、ConfigurationClassPostProcessor !!!!很重要,能完成注解的一个使用;方法:processConfigBeanDefinitions(registry)吃力配置类的定义信息;@Configuration @Bean @Import @Component @ComponentScan @ComponentScans;
2、PropertySourcePlaceHolderConfigurer
2、创建一个空的集合,用来存储执行过的BFPP;
3、判断当前beanFactory是否是BeanDefinitionRegistry 创建两个空的集合对象,分类存储BFPP和BDRPP
4、是;处理用户传进来的自定义的BFPP;便利每一个元素集合,
1、判断是否是BeanDefintionRegistryPostProcessor子类;
2、进行类型转换,执行BDRPP接口中的方法
3、放到regularPostProcessor集合中;
5、创建存放BDRPP的集合对象用来存储当前正在执行过程中的BDRPP
6、获取当前容器中国所有实现了BDRPP的对象 BeanDefinitionRegistryPostProcessor;
1、判断是否实现了 priorityOrdered接口
是 添加具体对象到currentRegistryProcessor集合中,并且将当前bdrpp的名字加入processedBeans中
2、将currentRegistryProcessors进行排序操作
3、将currentRegistryProcessors集合中的属性值合并到registryProcessors
4、执行bdrpp接口中的方法 inbokeBeanDefinitionRegistryPostProcessors
5、清空当前currentRegistryProcessors;
7、获取当前容器中所有实现了bdrpp接口的对象,并且判断是否实现orderd接口;
跟6的流程一样;
8、获取当前容器中所有实现了BDRPP接口的对象,如果没有实现PriorityOrdered接口,也没有实现Ordered的接口
跟6的流程一样
9、执行所有RegistryProcessors中对象的PostProcessBeanFactory接口的方法
10、执行所有regularProcessors中对象的postProcessorBeanFactory接口方法
11、优先处理实现了PriorityOrderd接口的BFPP对象,然后是Orderd接口的对象,最后是两者都没有实现的对象
调用BFPP中的postProcessorBeanFactory方法
6、注册BeanPostProcessorRegistryBeanPostProcessor(BeanFactory)
1、完成spring自带或者用户自定义的BeanPostProcessor的解析
7、initMessageSource 进行国际化相关的操作 MessageSource.Locale
8、initApplicationEverntMulticaster() 初始化事件广播器
使用监听者模式
1、创建多个事件类
2、注册多个事件类
3、初始化广播器
4、创建多个监听器
5、注册多个监听器
6、事件发布,通知广播器进行广播
7、监听器监听处理
9、onRefresh
1、在spring中默认没有任何实现、模板方法,但是在spirngboot中启动了web容器
10、registerListerners() 注册监听器
1、为了方便接受广播事件
11、finishBeanFactoryInitialization(beanfactory)完成所有非懒加载的单例对象的实例化操作
getBean->doGetBean->createBean->doCreateBean
从此方法开始进行对象的创建、包含了实例化、初始化、循环依赖、aop等核心逻辑的处理过程,此步骤是最核心关键点。
1、为上下文初始化类型转换器 converterService;
有三种转换器的实现方式:
converter s到t的转换
genericConverter 用于两种或者更多中类型之间转换的通用转换器接口
converterFactory converter转换器的工厂类,用来获取对应的转换器
2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析
3、尽早初始化loadTimeWeavweAware bean,以便尽早注册他们的转换器
4、禁止使用临时类加载器进行类型匹配
5、冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
6、实例化剩下的单例对象;
1、将所有的beanDefinition的名字创建一个集合
2、触发所有非延迟加载单例bean的初始化,遍历集合的对象 、合并父类beanDefinition
getMergedLocalBeanDefinition:在实例化之前,要把所有的基础的beanDefinition对象转化成RootBeanDefinition对象,进行缓存。后续在需要马上实例化的时候,直接获取定义信息,而定义信息中如果包含了父类,那么必须要先创建父类才有子类。
是否是factoryBean(如果使用beanFactory的接口,那么必须要严格遵守spring的bean的生命周期接口,从实例化,到初始化。此流程非常复杂且麻烦,如果有需要有一种更加便捷简单的方式创建,所以使用factoryBean这个接口,不需要遵循Spring的生命周期)
factoryBean 有三个方法:
getObjectType 返回类型
getObject 直接返回对象 加&返回实现factoryBean的对象,否则返回bean对象
isSingleton 是否单例
当使用factoryBean接口来创建对象的时候,一共创建了两个对象,1:实现了factoryBean接口的子类对象2:通过getObject方法返回的对象。此对象的创建过程就是由getObjectForBeanInstance方法调用实现的。都交给spring管理,但是object对象放到factoryBeanObjectCache内,FactoryBean放到singletonObjects一级缓存中。(earlySingletonObjects是二级缓存;singletonFactories 三级缓存; )如果不是单例对象,那么需要每次调用的时候重新创建,缓存中不会保存当前对象
12、finishRefresh 完成刷新
1、完成整个容器的启动,所有的对象都准备完成,可以进行后续业务流程的操作,清除上下文缓存,初始化生命周期处理器、发送刷新完成事件
13、resetCommonCaches清空运行过程中产生的缓存
如果运行过程中出现异常清空
1、销毁前面过程中创建的bean对象
2、重置当前容器的状态标致
3、抛出异常