一、概述

  源码如下:

@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); // Initialize message source for this context.
initMessageSource(); // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // Check for listener beans and register them.
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
} // Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

二、prepareRefresh()

  刷新前的预处理:
  

  1. initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
  2. getEnvironment().validateRequiredProperties();检验属性的合法等
  3. earlyApplicationEvents= new LinkedHashSet();保存容器中的一些早期的事件;

三、obtainFreshBeanFactory()

   获取BeanFactory:

  1. refreshBeanFactory();刷新【创建】BeanFactory

    • 创建了一个this.beanFactory = new DefaultListableBeanFactory();
    • 设置id;
  2. getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;
  3. 将创建的BeanFactory【DefaultListableBeanFactory】返回;

四、prepareBeanFactory(beanFactory);

  BeanFactory的预准备工作(BeanFactory进行一些设置):

  1. 设置BeanFactory的类加载器、支持表达式解析器...
  2. 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
  3. 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
  4. 注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
  5. 添加BeanPostProcessor【ApplicationListenerDetector】
  6. 添加编译时的AspectJ;
  7. 给BeanFactory中注册一些能用的组件;
    environment【ConfigurableEnvironment】、
    systemProperties【Map】、
    systemEnvironment【Map】

五、postProcessBeanFactory(beanFactory);

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

  • 子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置

  
以上是BeanFactory的创建及预准备工作
   

六、invokeBeanFactoryPostProcessors(beanFactory)

执行BeanFactoryPostProcessor的方法,BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;
两个接口:BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor

执行BeanFactoryPostProcessor的方法;

  1. 先执行BeanDefinitionRegistryPostProcessor的方法

    • 获取所有的BeanDefinitionRegistryPostProcessor;
    • 看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
      postProcessor.postProcessBeanDefinitionRegistry(registry)
    • 在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
      postProcessor.postProcessBeanDefinitionRegistry(registry)
    • 最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
      postProcessor.postProcessBeanDefinitionRegistry(registry)

  2. 再执行BeanFactoryPostProcessor的方法

    • 获取所有的BeanFactoryPostProcessor
    • 看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、postProcessor.postProcessBeanFactory()
    • 在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;postProcessor.postProcessBeanFactory()
    • 最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;postProcessor.postProcessBeanFactory()

七、registerBeanPostProcessors(beanFactory)

  注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的BeanPostProcessor、DestructionAwareBeanPostProcessor、InstantiationAwareBeanPostProcessor、SmartInstantiationAwareBeanPostProcessor、MergedBeanDefinitionPostProcessor【internalPostProcessors】
  

  1. 获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrderedOrdered接口来执行优先级
  2. 先注册PriorityOrdered优先级接口的BeanPostProcessor;把每一个BeanPostProcessor;添加到BeanFactory中beanFactory.addBeanPostProcessor(postProcessor);
  3. 再注册Ordered接口的
  4. 最后注册没有实现任何优先级接口的
  5. 最终注册MergedBeanDefinitionPostProcessor;
  6. 注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是applicationContext.addApplicationListener((ApplicationListener<?>) bean);

八、initMessageSource()

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

  1. 获取BeanFactory
  2. 看容器中是否有id为messageSource的,类型是MessageSource的组件;如果有赋值给messageSource;如果没有自己创建一个DelegatingMessageSource;MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
  3. 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);

九、initApplicationEventMulticaster()

  初始化事件派发器:

  1. 获取BeanFactory
  2. 从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
  3. 如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
  4. 将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入

十、onRefresh()

  留给子容器(子类):

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

十一、registerListeners()

  给容器中将所有项目里面的ApplicationListener注册进来:

  1. 从容器中拿到所有的ApplicationListener
  2. 将每个监听器添加到事件派发器中getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
  3. 派发之前步骤产生的事件;

十二、finishBeanFactoryInitialization(beanFactory)

  初始化所有剩下的单实例bean:beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean:

  1. 获取容器中的所有Bean,依次进行初始化和创建对象
  2. 获取Bean的定义信息;RootBeanDefinition
  3. Bean不是抽象的,是单实例的,是懒加载;

    • 判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
    • 不是工厂Bean。利用getBean(beanName) 创建对象

      • 0、getBean(beanName); ioc.getBean();
      • 1、doGetBean(name, null, null, false);
      • 2、先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);获取的
      • 3、缓存中获取不到,开始Bean的创建对象流程;
      • 4、标记当前bean已经被创建
      • 5、获取Bean的定义信息;
      • 6、【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】
      • 7、启动单实例Bean的创建流程;
       1)、createBean(beanName, mbd, args);
      2)、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象;【InstantiationAwareBeanPostProcessor】:提前执行;先触发:postProcessBeforeInstantiation();如果有返回值:触发postProcessAfterInitialization();
      3)、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)
      4)、Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean
      1)、【创建Bean实例】;createBeanInstance(beanName, mbd, args);利用工厂方法或者对象的构造器创建出Bean实例;
      2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
      3)、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
      赋值之前:
      1)、拿到InstantiationAwareBeanPostProcessor后置处理器; postProcessAfterInstantiation();
      2)、拿到InstantiationAwareBeanPostProcessor后置处理器;postProcessPropertyValues();
      =====赋值之前:===
      3)、应用Bean属性的值;为属性利用setter方法等进行赋值;
      applyPropertyValues(beanName, mbd, bw, pvs);
      4)、【Bean初始化】initializeBean(beanName, exposedObject, mbd);
      1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法
      BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
      2)、【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
      BeanPostProcessor.postProcessBeforeInitialization();
      3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd); 1)、是否是InitializingBean接口的实现;执行接口规定的初始化;2)、是否自定义初始化方法;
      4)、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization、BeanPostProcessor.postProcessAfterInitialization();
      5)、注册Bean的销毁方法;
      5)、将创建的Bean添加到缓存中singletonObjects;
      ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。;
      所有Bean都利用getBean创建完成以后;
      检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();

十二、finishRefresh()

完成BeanFactory的初始化创建工作;IOC容器就创建完成:

  1. initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
    加入到容器;
    写一个LifecycleProcessor的实现类,可以在BeanFactory
    void onRefresh();
    void onClose();
  2. getLifecycleProcessor().onRefresh();
    拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
  3. publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
  4. liveBeansView.registerApplicationContext(this);

十三、总结

  1. Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;

    • xml注册bean;
    • 注解注册Bean;@Service、@Component、@Bean、xxx
  2. Spring容器会合适的时机创建这些Bean
    • 用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
    • 统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
  3. 后置处理器;BeanPostProcessor
    • 每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
      AutowiredAnnotationBeanPostProcessor:处理自动注入
      AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
      xxx....
      增强的功能注解:
      AsyncAnnotationBeanPostProcessor
      ....
  4. 事件驱动模型;
    ApplicationListener;事件监听;
    ApplicationEventMulticaster;事件派发:

【Spring】容器刷新(refresh)流程解析的更多相关文章

  1. Spring容器的refresh()介绍

    Spring容器的refresh()[创建刷新]; 1.prepareRefresh()刷新前的预处理; 1).initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置 ...

  2. Spring容器启动源码解析

    1. 前言 最近搭建的工程都是基于SpringBoot,简化配置的感觉真爽.但有个以前的项目还是用SpringMvc写的,看到满满的配置xml文件,却有一种想去深入了解的冲动.折腾了好几天,决心去写这 ...

  3. spring容器的refresh方法分析

    spring源码版本5.0.5 Spring容器创建之后,会调用它的refresh方法刷新Spring应用的上下文. 首先整体查看AbstractApplicationContext#refresh源 ...

  4. spring加载bean流程解析

    spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步.不过作为朝夕相处的框架,我们必须得明白一个问题就是sprin ...

  5. Spring容器的初始化流程

    一.创建BeanFactory流程 1.流程入口 创建BeanFactory的流程是从refresh方法的第二步开始的,通过调用obtainFreshBeanFactory方法完成流程. Config ...

  6. Spring容器创建过程

    Spring容器的refresh()   创建刷新 1  prepareRefresh() 刷新前的预处理 1) initProPertySources() 初始化一些属性设置: 子类定义个性化的属性 ...

  7. 重新学习Spring注解——Spring容器

    44.[源码]-Spring容器创建-BeanFactory预准备 45.[源码]-Spring容器创建-执行BeanFactoryPostProcessor 46.[源码]-Spring容器创建-注 ...

  8. Spring注解驱动开发(六)-----spring容器创建【源码】

    Spring容器的refresh()[创建刷新] 1.prepareRefresh()刷新前的预处理 1).initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法 ...

  9. 44、[源码]-Spring容器创建-BeanFactory预准备

    44.[源码]-Spring容器创建-BeanFactory预准备 @Override public void refresh() throws BeansException, IllegalStat ...

随机推荐

  1. STM32实现Airplay音乐播放器

    AirPlay是苹果公司推出的一套无线音乐解决方案,我们手里的iPhone.iPad甚至是Apple Watch等设备还有电脑上的iTunes都支持AirPlay,但是支持AirPlay功能的音响设备 ...

  2. Spark 系列(十)—— Spark SQL 外部数据源

    一.简介 1.1 多数据源支持 Spark 支持以下六个核心数据源,同时 Spark 社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景. CSV JSON Parquet ORC JD ...

  3. [Spring cloud 一步步实现广告系统] 19. 监控Hystrix Dashboard

    在之前的18次文章中,我们实现了广告系统的广告投放,广告检索业务功能,中间使用到了 服务发现Eureka,服务调用Feign,网关路由Zuul以及错误熔断Hystrix等Spring Cloud组件. ...

  4. Oracle - SPM固定执行计划(一)

    一.前言 生产中偶尔会碰到一些sql,有多种执行计划,其中部分情况是统计信息过旧造成的,重新收集下统计信息就行了.但是有些时候重新收集统计信息也解决不了问题,而开发又在嗷嗷叫,没时间让你去慢慢分析原因 ...

  5. Redis总结(九)Linux环境如何安装redis

    以前总结Redis 的一些基本的安装和使用,由于是测试方便,直接用的window 版的reids,并没有讲redis在linux下的安装.今天就补一下Linux环境如何安装redis. 大家可以这这里 ...

  6. go 学习笔记之详细说一说封装是怎么回事

    关注公众号[雪之梦技术驿站]查看上篇文章 猜猜看go是不是面向对象语言?能不能面向对象编程? 虽然在上篇文章中,我们通过尝试性学习探索了 Go 语言中关于面向对象的相关概念,更确切的说是关于封装的基本 ...

  7. 由于Microsoft\VisualStudio\14.0\Designer\ShadowCache导致的一个异常问题

    本文引用了一个DynamicDataDisplay和DynamicControl两个类库,本来使用的时候都时正常的,愉快的运行着. DynamicDataDisplay:这是一个用于动态数据可视化的W ...

  8. shiro 定义realm

    public class UserRealm extends AuthorizingRealm { private UserService userService = new UserServiceI ...

  9. js设置,取得,清除cookie

    //取得cookie function getCookie(name) {  var nameEQ = name + "=";  var ca = document.cookie. ...

  10. 七缸发动机预热,docker swarm + .net core 高速飙车成功

    (图片来源:Microsoft Blog) 上周五上午在我们将 .net core 博客站点由 docker swarm 自动驾驶改为 docker-compose 手动驾驶后,依然发生了翻车,意料之 ...