Spring容器的refresh 创建刷新:

 

1-prepareRefresh刷新前的预处理:

initPropertySources 初始化一些属性配置,原来是空的,子类自定义的属性设置方法

getEnvironment().validateRequiredProperties();检验属性的合法性

this.earlyApplicationEvents = new LinkedHashSet<>();保存容器中的一些早期的事件

2-obtainFreshBeanFactory();获取BeanFactory

refreshBeanFactory(); 刷新BeanFactory;(在GenericApplicationContext类里面)
创建了this.beanFactory = new DefaultListableBeanFactory();
设置idthis.beanFactory.setSerializationId(getId());

getBeanFactory()返回刚才GenericApplicationContext构造器创建的BeanFactory对象
将创建的的BeanFactory[DefaultListableBeanFactory]返回

3-prepareBeanFactory(beanFactory); BeanFactory的预备工作,BeanFactory进行一些设置

1设置BeanFactory类的类加载器,支持表达式解析器。。。。。

2beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));添加部分的BeanPostProcessor

3设置忽略的自动装配的接口(就是不能通过实现接口进行加载),包括EnvironmentAware EmbeddedValueResolverAware

4beanFactory.registerResolvableDependency
注册可以解析的自动装配(就是通过autowire) 包括BeanFactory ResourceLoader ApplicationEventPublisher 5添加BeanPostProcessor(ApplicationListenerDetector) 6添加编译时的AspetJ 7给BeanFactory能用的组件
environment【ConfigurableEnvironment】
systemProperties 【Map<String, Object>】
systemEnvironment【Map<String, Object>】

4-postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作

子类通过重写该方法来BeanFactory创建并准备以后坐进一步的设置

###############################上面就是BeanFactory的创建几与准备工作

5-invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor

  BeanFactoryPostProcessor  BeanFactory后置处理器,在BeanFactory标准初始化之后执行

  两个接口:BeanFactoryPostProcessor   BeanDefinitionRegistryPostProcessor子接口

1-执行BeanFactoryPostProcessor的方法:
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
先执行这个后置处理器BeanDefinitionRegistryPostProcessor
1-获取所有的BeanDefinitionRegistryPostProcessor
2-看优先级排序,先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor
执行后置处理器方法postProcessor.postProcessBeanDefinitionRegistry
3-在执行实现了Ordered.class顺序接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry);
4-最后执行没有实现优先级或者顺序接口的BeanDefinitionRegistryPostProcessor
再执行BeanFactoryPostProcessor的方法
其实流程和上面那个处理器一样

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

1-获取所有的BeanPostProcessor
不同类型的BeanPostProcessor,在Bean创建前后的执行时机是不一样的
DestructionAwareBeanPostProcessor【存放位置】
InstantiationAwareBeanPostProcessor,【存放位置】
SmartInstantiationAwareBeanPostProcessor,【存放位置】
MergedBeanDefinitionPostProcessor【存放位置internalPostProcessors】
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); (后置处理器都有优先级) 2-注册PriorityOrderd优先级接口的BeanPostProcessor:
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
实际上就是将每一个BeanPostProcessor,添加到BeanFactory中
beanFactory.addBeanPostProcessor(postProcessor); 3-在注册Oreder接口的
4-最后注册么有实现任何接口的
5-最终注册的是MergedBeanDefinitionPostProcessor类型的
6-最后最后注册ApplicationListenerDetector:来创建Bean完成后检查是否是ApplicationListener,如果是的化就进行下面带#号的语句
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); ######this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);

7-initMessageSource();初始化MessageSource组件(座国际化功能,消息绑定,消息解析)

1-获取BeanFactory:
ConfigurableListableBeanFactory beanFactory = getBeanFactory(); 2-看容器中是否包含id为 messageSource组件
如果有就赋值给该类的属性
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
如果没有新建一个DelegatingMessageSource dms = new DelegatingMessageSource();
MessageSource 取出国际化配置文件中的某个key的值,能按照区域信息获取 3-把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,自动注入MessageSource即刻
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

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

1-获取BeanFactory
2-从BeanFactory中获取ApplicationEventMulticaster
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); 3-如果上一步没有配置,创建一个SimpleApplicationEventMulticaster
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); 4-将创建的ApplicationEventMulticaster 添加到BeanFactory中,以后可以自动注入
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);

9-onRefresh();留给子容器(子类)

   子类重写这个方法,在容器刷新的时候可以自定义逻辑

10-registerListeners();给容器中将所有项目里面的ApplicationListener注册进来

1-从容器中拿到ApplicationListener
getApplicationListeners()
2-将每个监听器,提娜佳到事件派发起
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); 3-派发之前步骤产生的事件:
getApplicationEventMulticaster().multicastEvent(earlyEvent);

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

1-beanFactory.preInstantiateSingletons();初始化剩下的单实例Bean
1-获取容器中所有的Bean,依次进行初始化和创建对象
beanNames = new ArrayList<>(this.beanDefinitionNames);
2-获取Bean的定义信息:RootBeanDefinition
3-如果bean不是抽象的额,是单实例的,是懒加载:
1-判断是否是FactoryBean,是否是实现FactoryBean接口的Bean,如果是工厂bean就会用工厂的getObject来创建对象
2-如果不是直接利用getBean(beanName)创建对象
getBean(beanName)怎么做:
1-调用doGetBean
2-先获取缓存中的单实例bean,如果能够获取到,Bean是之前被创建的(所有被创建锅的Bean都会被缓存起来)
Object sharedInstance = getSingleton(beanName);
3-获取不到,开始创建对象流程:
4-标记当前bean已经被创建markBeanAsCreated(beanName);
5-获取Bean的定义信息RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
6-获取当前Bean依赖的信息:String[] dependsOn = mbd.getDependsOn();并通过getBean创建出来
7-启动单实例Bean的创建过程if (mbd.isSingleton())
1-createBean(beanName, mbd, args)
2-让BeanPostProcess进行拦截执行
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
执行的类型是:InstantiationAwareBeanPostProcessor类型
触发Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
如果有放回值,执行 processor.postProcessAfterInitialization(result, beanName); 3-如果前面InstantiationAwareBeanPostProcessor没有返回代理对象
执行:Object beanInstance = doCreateBean(beanName, mbdToUse, args);

执行doCreateBean的流程

通过bean构造器创建Bean
instanceWrapper = createBeanInstance(beanName, mbd, args); applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用MergedBeanDefinitionPostProcessor的方法:
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);

位Bean属性赋值populateBean(beanName, mbd, instanceWrapper);
  赋值之前
  1-拿到InstantiationAwareBeanPostProcessor 后置处理器:
    执行bp.postProcessAfterInstantiation
  2-在其拿到InstantiationAwareBeanPostProcessor 后置处理器
    执行bp.postProcessPropertyValues
  3-应用Bean属性的值,为属性利用setter方法进行赋值现在才开始赋值applyPropertyValues(beanName, mbd, bw, pvs);
Bean初始化
  initializeBean(beanName, exposedObject, mbd);
  1-invokeAwareMethods(beanName, bean);执行Aware接口的方法。
    BeanNameAware
    BeanClassLoaderAware
    BeanFactoryAware
  2-执行后置处理器初始化之前的方法:BeanPostProcessor
   wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    调用processor.postProcessBeforeInitialization(result, beanName);
  3-执行初始化方法:InitializingBean
    1-判断是否是InitializingBean接口,执行规定的初始化方法:
    2-判断是否自定义初始化方法
  4-执行后置处理器初始化
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
      BeanPostProcessor.postProcessAfterInitialization
注册Bean的销毁方法:
  registerDisposableBeanIfNecessary(beanName, bean, mbd);
 

最后是将Bean添加到缓存当中的singletonObjects

备注:IOC容器就是这些Map,很多Map里面保存了单实例Bean,环境信息等

DefaultListableBeanFactory

所有Bean都利用getBean完成之后:
检查所有的Bean是否是SmartInitializingSingleton接口的,如果是,
就执行smartSingleton.afterSingletonsInstantiated();

12-finishRefresh() 完成BeanFactory的初始化创建工作,IOC容器就创建完成!!!

初始化和生命周期有关的后置处理器initLifecycleProcessor();LifecycleProcessor
写一个LifecycleProcessor的实现类,可以在BeanFactory两个阶段
void onRefresh() void onClose()
如果没有自定义生命周期,则容器会新建一个 new DefaultLifecycleProcessor();并注册到容器当中去:
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); 拿到前面的生命周期,回调onRefresh()方法,getLifecycleProcessor().onRefresh(); 发布容器刷新完成事件publishEvent(new ContextRefreshedEvent(this)); LiveBeansView.registerApplicationContext(this);

spring容器总结

1-Spring容器在启动的时候,贤惠保存所有注册进来的Bean定义信息

  1-1xml注册bean<bean>

  1-2注解注册Bean @Service @Component

2-Spring容器会合适的时机创建那就这些Bean

  2-1用到这个Bean的时候,利用getBean创建Bean,并保存到容器中

  2-2统一创建所有剩下的Bean,finishBeanFactoryInitialization

3-后置处理器:

  3-1每个Bean的创建完成,都会使用各种后置处理器进行处理,来增强bean的功能

    AutowiredAnnotationBeanPostProcessor 处理自动注入

    AnnotationAwareAspectJAutoProxyCreator 做AOP功能

    增强的功能注解,都是通过后置处理器来完成的

    AsyncAnnotationBeanPostProcessor

4-事件驱动模型:

  ApplicationListener:事件监听

  ApplicationEventMulticaster事件派发

    

  

spring源码-ioc容器周期的更多相关文章

  1. Spring源码-IOC部分-容器初始化过程【2】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  2. Spring源码-IOC部分-容器简介【1】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  3. Spring源码-IOC部分-自定义IOC容器及Bean解析注册【4】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  4. Spring源码——IOC控制反转

    1.基础知识 Spring有两个核心功能,分别是ioc和aop,其中ioc是控制反转,aop是切面编程. 在ioc中,还有一个名次叫DI,也就是依赖注入.嗯,好像IOC和DI是指同一个,好像又感觉他俩 ...

  5. Spring源码-IOC部分-Bean实例化过程【5】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  6. Spring源码学习-容器BeanFactory(一) BeanDefinition的创建-解析资源文件

    写在前面 从大四实习至今已一年有余,作为一个程序员,一直没有用心去记录自己工作中遇到的问题,甚是惭愧,打算从今日起开始养成写博客的习惯.作为一名java开发人员,Spring是永远绕不过的话题,它的设 ...

  7. Spring源码-IOC部分-Spring是如何解决Bean循环依赖的【6】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  8. Spring源码-IOC部分-Xml Bean解析注册过程【3】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  9. Spring源码-IOC部分-循环依赖-用实例证明去掉二级缓存会出现什么问题【7】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

随机推荐

  1. 『无为则无心』Python面向对象 — 55、多层继承和继承中的私有成员

    目录 1.Python支持多层继承 (1)多层继承实现 (2)多层继承和多重继承区别 2.继承中的私有成员 (1)继承中父类私有属性和私有方法 (2)获取和修改私有属性值 1.Python支持多层继承 ...

  2. Clickhouse写入问题汇总

    Clickhouse写入问题汇总 Zookeeper相关 当clickhouse在建表时使用了Replicated引擎族时, 会对zookeeper有非常重的依赖, 这时候就要注意zookeeper集 ...

  3. 自助BI工具是BI行业发展的趋势吗?

    自助BI和分析通过提供交互式数据可视化,图表,图形,报告和分析,帮助业务用户做出决策.将大量数据导出到电子表格以转换为图表和数据透视表的日子现在已经结束.自助BI工具提供基于浏览器的客户端界面,适用于 ...

  4. excel制作折线图太麻烦?试试这些折线图在线生成工具

    折线图是以折线的上升或下降来表示统计数量的增减变化的统计图,叫作折线统计图.用折线的起伏表示数据的增减变化情况,不仅可以表示数量的多少,而且可以反映数据的增减变化情况.并且折线图也是目前最方便的一种统 ...

  5. 【C# 练习】通过ZoomGame这个案例加强对 反射 插件 特性的认识

    游戏情景设定: 有一个游戏机,里面出现几种动物让儿童选择.选择完动物后,在输入数值让动物叫几次. 动物类型以插件的形势存在,可以外包给其他人开发,并提供了开发接口AnimalTool.SDK.dll. ...

  6. Oracle表的约束

    表的约束定义:表的约束是 ORACLE 数据库中应用在表数据上的一系列强制性规则 按照约束用途分类: PRIMARY KEY:主键约束 FOREIGN KEY:外键约束 CHECK:检查约束 UNIQ ...

  7. 由浅入深--ORM简介

    一.ORM简介 从传统的JDBC开始说起 下面是通过JDBC连接Oracle的步骤,如下代码所示: Connection conn = null; PreparedStatement stmt = n ...

  8. Qt:Shadow Build

    每个编辑器有Build和Run两个设置界面. 在Build界面上,有一个"Shadow build"复选框.如果勾选此项,编译后将在项目的同级目录下建立一个编译后的文件目录,目录名 ...

  9. pandas模块篇(之二)

    今日内容概要 布尔选择器 索引 数据对齐 数据操作(增出改查) 算术方法 DataFrame(Excel表格数据) 布尔选择器 import numpy as np import pandas as ...

  10. python+pytest接口自动化(4)-requests发送get请求

    python中用于请求http接口的有自带的urllib和第三方库requests,但 urllib 写法稍微有点繁琐,所以在进行接口自动化测试过程中,一般使用更为简洁且功能强大的 requests ...