码迷,mamicode.com
首页 > 编程语言 > 详细

spring ioc

时间:2021-06-06 19:09:27      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:模式   mamicode   ash   接口   类重写   rap   find   factory   spring容器   

spring

1. prepareRefresh()

Prepare this context for refreshing.
刷新前的预处理
表示在真正做refresh操作之前需要准备做的事情:

1. 设置Spring容器的启动时间,
2. 开启活跃状态,撤销关闭状态
3. 验证环境信息里一些必须存在的属性等
// 清空数据
//Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
	this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
	// Reset local application listeners to pre-refresh state.
	this.applicationListeners.clear();
	this.applicationListeners.addAll(this.earlyApplicationListeners);
}

2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

获取BeanFactory;默认实现是DefaultListableBeanFactory

加载BeanDefition 并注册到 BeanDefitionRegistry

→refreshBeanFactory();

  1. 实例化 DefaultListableBeanFactory

  2. 设置序列化id

  3. 自定义bean工厂的一些属性(只有两个配置:是否覆盖、是否允许循环依赖)

  4. 加载(读取并注册)应用中的BeanDefinitions :

    loadBeanDefinitions(beanFactory) :读取applicationContext.xml这样的自定义的及默认的bean配置,并注册到this.beanDefinitionMap里

3. prepareBeanFactory(beanFactory)

BeanFactory的预准备工作(BeanFactory进行一些设置,比如context的类加载器等),classloader& post-processor

4. postProcessBeanFactory(beanFactory);

BeanFactory准备工作完成后进行的后置处理工作

直接运行好像没有调用的。给第三方用的吧。

5.invokeBeanFactoryPostProcessors(beanFactory);

实例化并调用所有已注册的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor

6.registerBeanPostProcessors(beanFactory);

注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行

  1. AutowiredAnnotationBeanPostProcessor
  2. aop处理器

技术图片

7.initMessageSource();

初始化MessageSource组件(做国际化功能;消息绑定,消息解析)bean:messageSource

8.initApplicationEventMulticaster();

初始化事件派发器 bean:applicationEventMulticaster

9.onRefresh();

空实现。子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器

10.registerListeners();

注册实现ApplicationListener接口的bean

11.finishBeanFactoryInitialization(beanFactory);

实例化所有单例bean

  1. 把ConversionService

  2. 注册属性处理器PropertyResolver默认StringValueResolver

  3. beanFactory.preInstantiateSingletons(); 实例化所有立即加载的单例bean

    step1:从缓存中获取bean

    准备生成iBbean先查询是否已创建或正在创建该bean(上面5.invokeBeanFactoryPostProcessors(beanFactory);已经构建了部分的bean)

    用了singletonsCurrentlyInCreation Set存储正在创建的bean,这里没有开始创建,所以这里没有进if判断。

    技术图片

    step2 : 标记未正在创建

    技术图片

    this.alreadyCreated.add(beanName);

    step3: 开始创建bean

    技术图片

    step 3.1:

    this.singletonsCurrentlyInCreation.add(beanName) 把A添加到正在创建的map中

    调用A的()→ getObject() lambda函数

    技术图片

    这里是处理的逻辑

    技术图片

    step 3.2: doCreateBean真正的创建bean

    先创建简单bean(只调用构造器)

    技术图片

    AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition 找到需要autowired的值, dowithLocalfields 和 dowithlocalmethods ,封装返回new InjectionMetadata(clazz, elements)

    技术图片

    技术图片

    放入三级缓存中this.singletonFactories.put(beanName, singletonFactory); 前提如果允许循环依赖且bean是单例模式 ,getEarlyBeanReference —> 第三个入参就是对应的简单bean。

    技术图片

    技术图片

    开始属性填充populateBean

    技术图片

    调用AutowiredAnnotationBeanPostProcessor#postProcessProperties

    技术图片

    上面已经拿到了需要装配的信息,这里findAutowiringMetadata直接能从缓存this.injectionMetadataCache中拿到

    技术图片

    准备注入bean B

    B 封装成 DependencyDescriptor desc = new DependencyDescriptor(field, this.required);

    处理依赖org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

    这里matchingBeans只获取到了lagouBean(单个bean和多个bean的操作不一样,后面再看看)

    后面回到了

    org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate

    —> org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

    —>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

    技术图片

    初始化构造器之后,populatebean, 处理lagoubean的依赖itBean ,从各级缓存中获取bean,org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean), 此时可以把itBean从三级缓存this.singletonFactories中放到二级缓存this.earlySingletonObjects中

    技术图片

    技术图片

    itBean —> this.earlySingletonObjects

    lagouBean —> this.earlySingletonObjects

    lagouBean注入itBean

    技术图片

    populateBean后 调用初始化方法,应用BeanPostProcessor后置处理器

    技术图片

    after&aop

    开始第二次earlySingletonExposure判断,从缓存获取getSingleton,但是此时不允许循环引用(只能从1,2级缓存中拿bean 主要原因为不允许bean在上面初始化后被改变)

    技术图片

    getSingleton afterSingletonCreation 把singletonsCurrentlyInCreation中删除lagouBean

    技术图片

    getSingleton addSingleton(beanName, singletonObject);

    技术图片

    此时lagouBean初始化完成。

    itBean —> this.earlySingletonObjects

    lagouBean —> this.singletonObjects

    返回的结果在这里inject

    技术图片

    itBean populate完成,后面操作和lagouBean操作一致。最终到下面的步骤

    getSingleton addSingleton(beanName, singletonObject);

    技术图片

    此时lagouBean初始化完成。

    itBean —> this.earlySingletonObjects

    lagouBean —> this.singletonObjects

    初始化所有的bean完成,通知

    org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated

    12. finishRefresh();

    1.clearResourceCaches();

    清除资源缓存

    2.initLifecycleProcessor();

    lifecycleProcessor加入到this.singletonObjects

    3.getLifecycleProcessor().onRefresh();

    第二步的lifecycle刷新

    4.publishEvent(new ContextRefreshedEvent(this));

    发布事件

    5.LiveBeansView.registerApplicationContext(this);

spring ioc

标签:模式   mamicode   ash   接口   类重写   rap   find   factory   spring容器   

原文地址:https://www.cnblogs.com/dinry/p/14854298.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!