Spring源码分析,很完整的源码分析,扩展流程,扩展原理,执行顺序,全都有

Spring启动流程

【ClassPathXmlApplicationContext】xml方式启动为例

1. 初始化参数

spring会把容器接口的第一个参数设置为configLocations,作为基础的配置文件绑定,随后调用refresh方法

$1=ClassPathXmlApplicationContext
  $1#super(parent);
  //把传入的配置文件配置给Context本身的configLocations属性
  $1# this.setConfigLocations("传入的配置文件");
  if (refresh) {
    $1# this.refresh();//执行Context的刷新操作
  }

2. 初始化及加载的全流程

$1=AbstractApplicationContext
  $1#refresh()
    synchronized($1# this.startupShutdownMonitor) {
      //刷新前的预处理,准备上下文的刷新
      $1# this.prepareRefresh()
      //通知子类刷新内部的BeanFactory,获取BeanFactory,类型为ConfigurableListableBeanFactory 
      $1# this.obtainFreshBeanFactory()=@1
      //BeanFactory的预准备
      $1# this.prepareBeanFactory(@1)
      try {
        //允许上下文子类对BeanFactory进行后置处理,BeanFactory准备完成后置处理,【模板方法】
        $1# this.postProcessBeanFactory(@1)
        //调用上下文中注册为工厂处理器的Bean,BeanFactoryPostProcessor的处理调用
        $1# this.invokeBeanFactoryPostProcessors(@1)
        //实例化注册BeanPostProcessor(Bean创建的拦截处理器),在创建bean的前后执行
        $1# this.registerBeanPostProcessors(@1)
        //初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
        $1# this.initMessageSource()
        //初始化事件派发器
        $1# this.initApplicationEventMulticaster()
        //子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat等WEB服务器,【模板方法】
        $1# this.onRefresh()
        //注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean
        $1# this.registerListeners()
        //BeanFactory内容初始化
        $1# this.finishBeanFactoryInitialization(@1)
        //完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法
        $1# this.finishRefresh()
      } catch (BeansException var9) {
        $1# this.destroyBeans();
        $1# this.cancelRefresh(var9);
        throw var9;
      } finally {
        $1# this.resetCommonCaches();
      }
   }
2.1 this.prepareRefresh() 刷新前的预处理

实现在真正做refresh操作之前需要准备做的事情:

  • 设置Spring容器的启动时间
  • 开启活跃状态
  • 撤销关闭状态
  • 预留【initPropertySources()】给子类留下配置文件加载的【模板方法
    • 看到springboot或者Springmvc这里需要注意看
  • 验证环境信息里一些必须存在的属性(目前没看到有什么作用)
  • 初始化或者传递获取应用事件的处理
    • 看到springboot或者Springmvc这里需要注意看
    • 看到springboot的时候这里会有初始的值
$1=AbstractApplicationContext
  $1#prepareRefresh();
    $1#initPropertySources();//钩子方法
    if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
    }
    this.earlyApplicationEvents = new LinkedHashSet<>();
2.2 this.obtainFreshBeanFactory() 获取BeanFactory

获取BeanFactory,默认实现是DefaultListableBeanFactory,这里获取的BeanFactory已经有了BD

  • 先判断是否存在BeanFactory,存在清空所有的引用对象(各级缓存和各种map)
  • 实例化 DefaultListableBeanFactory
  • 给BeanFactory设置序列化id
  • 定制BeanFactory的一些属性(是否覆盖、是否允许循环依赖)
  • 加载应用中的BeanDefinitions
    org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions自定义解析
    • 这里的configLocations解析,即xml解析就是dom4j啥的,主要可以看下注解类的解析
$1=AbstractApplicationContext
  $1#obtainFreshBeanFactory()
    $2=AbstractRefreshableApplicationContext#refreshBeanFactory//$2是$1的子类
    $2#refreshBeanFactory()
      // 定制bean工厂的一些属性
 	  $2#customizeBeanFactory()
	  // 加载应用中的BeanDefinitions
	  $2#loadBeanDefinitions()
2.3 this.prepareBeanFactory() BeanFactory预处理

BeanFactory的预准备工作,对BeanFactory进行一些设置,比如context的类加载器等

  • 设置Bean的类加载器

  • 设置Bean的表达式解析器

  • 设置资源编辑注册

  • 添加一个BeanPostProcessor

    • ApplicationContextAwareProcessor.class

      Spring重要扩展点:Aware相关的出发都来自于这个类

  • 设置加载豁免的类型

    • EnvironmentAware
    • EmbeddedValueResolverAware
    • ResourceLoaderAware
    • ApplicationEventPublisherAware
    • MessageSourceAware
    • ApplicationContextAware
  • 注册BeanFactory接口的Bean为自身

  • 注册ResourceLoader接口的Bean为自身

  • 注册ApplicationEventPublisher接口的Bean为自身

  • 注册ApplicationContext接口的Bean为自身

  • 添加一个BeanPostProcessor

    • ApplicationListenerDetector.class

      Spring重要扩展点:事件相关的注册基本都来自于这个类

  • 在容器处理之前先注册environment的单例

  • 在容器处理之前先注册systemProperties的单例

  • 在容器处理之前先注册systemEnvironment的单例

$1=AbstractApplicationContext
  $1#prepareBeanFactory()
    $2=ConfigurableListableBeanFactory@1
      $3#addBeanPostProcessor(new ApplicationContextAwareProcessor(@1));
      $3#addBeanPostProcessor(new ApplicationListenerDetector(@1));
2.4 this.postProcessBeanFactory(@1) BeanFactory创建后预留的模板方法

这个方法时留给子类实现的模板方法,作用时可以在BeanFactory准备完成后做处理,此时已经有初始化BD的BeanFactory了

2.5 this.invokeBeanFactoryPostProcessors(@1) 执行BeanFactoryPostProcessor

这个步骤主要触发BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor)相关的内容,先调用BeanDefinitionRegistryPostProcessor在调用BeanFactoryPostProcessor,不然BD修改了,就和BeanFactory不一致了

  • 首先看BeanFactory是不是一个BeanDefinitionRegistry

  • 如果是的话[BeanDefinitionRegistryPostProcessor->BeanFactoryPostProcessor执行点postProcessBeanDefinitionRegistry,postProcessBeanFactory]

    • 调用#postProcessBeanDefinitionRegistry()的顺序和内容
      1. 先执行上下文中给其设置的BeanDefinitionRegistryPostProcessor
        • 如果实现BeanDefinitionRegistryPostProcessor直接调用
        • 未实现BeanDefinitionRegistryPostProcessor加入到 regularPostProcessors
      2. 执行同时实现BeanDefinitionRegistryPostProcessor、PriorityOrdered的处理
      3. 执行同时实现BeanDefinitionRegistryPostProcessor、Ordered的处理
      4. 最后执行仅实现BeanDefinitionRegistryPostProcessor的处理
    • 调用#postProcessBeanFactory()的顺序和内容
      1. 以上所有的实现BeanDefinitionRegistryPostProcessor的处理
      2. regularPostProcessors中实现BeanFactoryPostProcessor的处理
  • 如果不是BeanDefinitionRegistry[BeanFactoryPostProcessor执行点postProcessBeanFactory]

    • 执行上下文中给其设置的BeanFactoryPostProcessor调用#postProcessBeanFactory()
  • 调用#postProcessBeanFactory()的顺序和内容

    1. 干刚刚执行过的全部排除,防止二次执行
    2. 执行同时实现BeanFactoryPostProcessor、PriorityOrdered的处理
    3. 执行同时实现BeanFactoryPostProcessor、Ordered的处理
    4. 最后执行仅实现BeanFactoryPostProcessor的处理
  • 添加一个BeanPostProcessor

    • LoadTimeWeaverAwareProcessor.class

      Spring重要节点:AOP相关内容,实现了BeanPostProcessor

$1=AbstractApplicationContext
  $1#invokeBeanFactoryPostProcessors()
    $2=PostProcessorRegistrationDelegate
      $2#invokeBeanFactoryPostProcessors()
        ...
    	//调用#postProcessBeanDefinitionRegistry()
    	$2#invokeBeanDefinitionRegistryPostProcessors()
    	...
        //调用#postProcessBeanFactory()
    	$2#invokeBeanFactoryPostProcessors()
   		$3=ConfigurableListableBeanFactory@1
		  $3#addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
2.6 this.registerBeanPostProcessors(@1) 注册BeanPostProcessor

这个步骤主要注册MergedBeanDefinitionPostProcessor(BeanPostProcessor)相关的内容

  • 添加一个BeanPostProcessor

    • BeanPostProcessorChecker.class

      Spring重要校验:判断BeanPostProcessor相关,没看明白

  • 注册流程

    1. 注册同时实现BeanPostProcessor、PriorityOrdered的处理
      • 把其中的MergedBeanDefinitionPostProcessor放到internalPostProcessors
    2. 注册同时实现BeanPostProcessor、Ordered的处理
    3. 注册仅实现BeanPostProcessor的处理
    4. 注册internalPostProcessors中的MergedBeanDefinitionPostProcessor(其实之前注册过了,重新注册是为了排序,保证MergedBeanDefinitionPostProcessor处于列表的后面)
  • 添加一个BeanPostProcessor

    • ApplicationListenerDetector.class

      和上面注册的是一样的这里是为了调整顺序

  • 注册结果beanPostProcessors列表中

    1. 同时实现BeanPostProcessor、PriorityOrdered
    2. 同时实现BeanPostProcessor、Ordered
    3. 仅实现BeanPostProcessor
    4. 同时实现MergedBeanDefinitionPostProcessor、PriorityOrdered
    5. 同时实现MergedBeanDefinitionPostProcessor、Ordered
    6. 仅实现MergedBeanDefinitionPostProcessor
    7. ApplicationListenerDetector(保证列尾是这个事件注册)

分析

  • PriorityOrdered的BeanPostProcessor在实例化时不会被其他BeanPostProcessor执行
  • Ordered的BeanPostProcessor在实例化时不会被仅有BeanPostProcessor执行
$1=AbstractApplicationContext
  $1#invokeBeanFactoryPostProcessors()
    $2=PostProcessorRegistrationDelegate
      //这里未来需要看,不知道为啥要这么做
	  beanFactory.addBeanPostProcessor(       );
2.7 this.initMessageSource() 没有看

感觉意义不大,暂时不看

2.8 this.initApplicationEventMulticaster() 初始化初始化事件派发器

实例化事件派发器

  • 如果此时容器中已经有满足下面条件的那就使用那个bean,注意,此时容器没有实例化Bean需要自己单独处理
    • 名为 applicationEventMulticaster
    • 类型为ApplicationEventMulticaster.class
  • 如果不满足上面的条件,那直接new了一个默认的
    • SimpleApplicationEventMulticaster.class
2.9 this.onRefresh() 特定上下文刷新

这里是在执行Bean的实例化步骤之前,子类可以重写这个方法,在容器刷新的时候可以自定义逻辑;如Springboot使用这里创建Tomcat等WEB服务器,是【模板方法】

2.10 this.registerListeners() 注册应用的监听器

注册应用的监听器并把earlyApplicationEvents中的事件发布

  • 先把容器中预先设置的事件监听器注册到事件派发器
    • 这里对事件监听器的处理有一些特殊,会判断是否是AOP的代理对象
    • 如果是AOP的代理对象还需要判断没看明白判断啥
  • 再把BeanFactory中的事件监听器注册到事件派发器
  • 最后发布earlyApplicationEvents预先添加的事件,这里默认是空的
2.11 this.finishBeanFactoryInitialization(@1) 初始化所有非懒加载的Bean

初始化所有非懒加载的Bean

  • 实例化实现了LoadTimeWeaverAware的类,保证所有LoadTimeWeaverAware的Bean都在此时初始化出来

  • 停用临时类加载器启用在哪没注意

  • 冻结容器中的BD数量和名字

  • 实例化所有非lazy单例进行遍历

    • 获取mergedBD(RootBeanDefinition)

    • 判断是不是抽象、单例、懒加载

    • 获取Bean

      • 获取Bean,如果是FB无限往里获取直到没有$

      • 从singleobjects获取对应Bean

        一级缓存完全体singletonObjects
        二级缓存光杆实例earlySingletonObjects 如果这个类处于创建中才查二三级缓存
        三级缓存初始工厂singletonFactories

      • 判断Bean是不是正在创建中,是就报错

      • 设置Bean 为创建中

      • 获得mergedBD(RootBeanDefinition)

      • 获取依赖的Bean并遍历获取Bean

      • 实例化这个Bean

        • 尝试从singleobjects取

        • 回调Spring标志的SF

          • 反射Bean的Class

            这里面涉及一个变量,BD的beanclass,这个变量声明的Object,在没进这步之前都是String,进了之后会解析成Class类型

          • [InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessBeforeInstantiation]

            InstantiationAwareBeanPostProcessor(实现此接口的类在进入createbean的过程中未创建bean的时候,此时已经有了Bean的class,这时候返回的Obj就是Bean)

          • 创建Bean

            • 获取BeanWrapped
            • [MergedBeanDefinitionPostProcessor->BeanPostProcessor执行点postProcessMergedBeanDefinition]
          • 把刚刚的Bean使用lamba存入singletonFactories、

            • getEarlyBeanReference

              感觉是通过这个获取Bean,如果直接是完全体就获取,中间体就进if

          • 给Bean添加属性

            • [InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessAfterInstantiation]

            • [InstantiationAwareBeanPostProcessor->BeanPostProcessor执行点postProcessProperties]

              调用此方法可以对注入的内容进行修改

            • 把Bean的属性存入BW

          • 初始化Bean

            • 调用Aware
              • [BeanNameAware->Aware执行点setBeanName]
              • [BeanClassLoaderAware->Aware执行点]setBeanClassLoader
              • [BeanFactoryAware->Aware执行点setBeanFactory]
            • [BeanPostProcessor执行点postProcessBeforeInitialization]
              • 有一个关键类ApplicationContextAwareProcessor会调起其他执行点
                • [EnvironmentAware->Aware执行点setEnvironment]
                • [EmbeddedValueResolverAware->Aware执行点setEmbeddedValueResolver]
                • [ResourceLoaderAware->Aware执行点setResourceLoader]
                • [ApplicationEventPublisherAware->Aware执行点setApplicationEventPublisher]
                • [MessageSourceAware->Aware执行点setMessageSource]
                • [ApplicationContextAware->Aware执行点setApplicationContext]
            • 执行初始化函数同时InitializingBean执行点
              • [InitializingBean执行点afterPropertiesSet]
              • 执行配置的init函数
          • 把创建好的Bean放到singletonObjects

            删除其他两个级别的缓存只存入到singletonObjects

          • 待到全部Bean都创建好并放到执行InitializingBean,遍历Bean进行[SmartInitializingSingleton执行点afterSingletonsInstantiated]


    分析

    • mergedBD的作用就是合并BD,防止出现一个Bean名字多个对应关系却没有默认(@Primary)
$1=AbstractApplicationContext
  #finishBeanFactoryInitialization()
    for(String weaverAwareName : weaverAwareNames) {
       //实例化实现了LoadTimeWeaverAware的类
       #getBean(weaverAwareName); 
    }
    // 实例化所有立即加载的单例bean
    $1.beanFactory.preInstantiateSingletons();
    $2=DefaultListableBeanFactory//$1.beanFactory
       //获取Bean,若果是FB无限往里获取直到没有$
       $2#getBean(beanName);
         //AbstractBeanFactory真实获取Bean
         $2#doGetBean();
           //从singleobjects获取对应Bean
    	   $2#getSingleton();
             //回调Spring标志的SF
    		 $3=$1&Lambda
             $3#createBean();
               //InstantiationAwareBeanPostProcessor执行点
			   $3#resolveBeforeInstantiation();
               //创建Bean
   			   $3#doCreateBean();
                 //获取BeanWrapped(实例化)
    			 $3#createBeanInstance()
    			 //MergedBeanDefinitionPostProcessor执行点
    			 $3#applyMergedBeanDefinitionPostProcessors()
                 //把刚刚的Bean存入earlySingletonObjects
                 $3#addSingletonFactory(Lambda[getEarlyBeanReference()]);
    			 //给Bean添加属性
    			 $3#populateBean();
                   //InstantiationAwareBeanPostProcessor执行点
				   ibp.postProcessAfterInstantiation();
                   //InstantiationAwareBeanPostProcessor执行点
                   ibp.postProcessProperties();
                   //把Bean的属性存入BW(属性填充)
                   #applyPropertyValues();
                 $3#initializeBean();
    			   //调用Aware相关执行点
                   $3#invokeAwareMethods();
    			   //BeanPostProcessor执行点
                   $3#applyBeanPostProcessorsBeforeInitialization();
    			   //执行初始化函数同时InitializingBean执行点
    			   $3#invokeInitMethods()
                     //执行配置的init函数
                     $3#invokeCustomInitMethod()
             //把创建好的Bean放到singletonObjects
             $2#addSingleton();  
       //待到全部Bean都创建好并放到执行InitializingBean
       for.smartSingleton.afterSingletonsInstantiated();

finishRefresh

完成context的刷新

  • 调用LifecycleProcessor的onRefresh()方法

    [Lifecycle执行点start]

  • 发布事件(ContextRefreshedEvent)

$1=AbstractApplicationContext
  #finishRefresh()
    //调用LifecycleProcessor的onRefresh()方法,Lifecycle执行点
    $1#getLifecycleProcessor().onRefresh()//调用LifecycleProcessor的回调
    //发布事件(ContextRefreshedEvent)
    $1#publishEvent(new ContextRefreshedEvent(this));//时间干了什么
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值