📓 Archive

00_SPRING_STARTUP

FGJ: Create:2024/07/18 Update: (2024-10-24)

  • Intro(Startup Process) #

    spring.version = 4.3.7.RELEASE

    Tip

    1.) ApplicationContext继承了BeanFactory接口,在内部实现中采用委托的方式调用正真的beanfactory.

    • 解析流程 #

      1).ClassPathXmlApplicationContext为例,新建一个应用上下文:new ClassPathXmlApplicationContext("_framework/spring/res/factory-bean.xml");


      2). 紧接着通过super(parent)调用父类构造器,一直往上传,直到AbstractApplicationContext,调用自己无参构造器this();后,使用setParent(parent);设置父属性。
      this()内部获取一个PathMatchingResourcePatternResolver().

      3). 然后是设置配置文件位置setConfigLocations(configLocations);,对于每一个配置文件,都会通过getEnvironment()获取环境变量StandardEnvironment对象解决(配置文件)配置文件路径中的占位符。

      4). 接下来进入主题AbstractApplicationContext#refresh();

      • refresh() #

        • 01). prepareRefresh() #


          对于刷新这个上下文做准备。记录启动时间,关闭状态,激活状态。
          以及留给子类去初始化propertySource的方法initPropertySources();
          获取环境并校验通过ConfigurablePropertyResolver#setRequiredProperties设置的必需属性,委托给 AbstractPropertyResolver 去执行校验。
          另外准备一个保存应用事件的set容器。

        • 02). obtainFreshBeanFactory() #


          获取一个新的bean工厂。

          protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;由子类去处理。


          通过createBeanFactory()方法new一个 DefaultListableBeanFactory bean工厂

          customizeBeanFactory(beanFactory);根据需要设置bean定义覆盖和循环引用的标志。

          • 02.1). loadBeanDefinitions #

            loadBeanDefinitions(beanFactory);加载bean定义,是抽象类AbstractRefreshableApplicationContext中定义的方法,由子类AbstractXmlApplicationContext去实现。


            创建beanDefinitionReader,传递benafactory给父类AbstractBeanDefinitionReader初始化 resourceLoaderenvironment 属性。但是在后续步骤中,使用了applicationContext的环境覆盖了自己刚才初始化的,包括ResourceLoader也一样。并且在reader对象中保存当前beanfactory,方便后续进行操作。

            initBeanDefinitionReader(beanDefinitionReader) ,初始化reader属性,比如设置validate=true.
            loadBeanDefinitions(beanDefinitionReader) ,使用reader从配置文件中加载beandefinitions到beanfactory中。

        • 03). prepareBeanFactory(beanFactory) #


          准备/配置beanfactory为接下来的使用,配置一些标准的特性,比如上下文加载器和后置处理器。
          1). 增加两个默认的bean后置处理器ApplicationContextAwareProcessor,ApplicationListenerDetector
          2). 其中的resolvableDependency用来注册一些默认类型的对象。例如有ApplicationContext类型的注入,当在population的时候通过findAutowireCandidates()方法中就可以使用到刚才默认的这些值了。

        • 04). postProcessBeanFactory(beanFactory) #


          允许子类修改应用上下文中的内部beanfactory在初始化完成之后。所有的beandefinitions已经加载完成,但是并没有实例化。所以此处子类可以适当添加一些bean后置处理器。

        • 05). invokeBeanFactoryPostProcessors(beanFactory) #


          调用beanfactory的后置处理器。当前上下文通过getBeanFactoryPostProcessors()获取到为0,所以忽略。但是mvc或者boot就不会为0了。

        • 06). registerBeanPostProcessors(beanFactory) #


          注册bean的后置处理器。当前上下文也为0,所以忽略。

        • 07). initMessageSource() #


          主要用来消息国际化,此处会实例化一个叫MessageSource类型的bean对象(如果配置的话)。 【demo参考】

        • 08). initApplicationEventMulticaster() #


          和上面的国际化差不多,默认给容器中注册一个事件多播器ApplicationEventMulticaster在如下的 10.registerListeners()中进行配置注册

        • 09). onRefresh() #


          空的模板方法,web类型的ac主要用来创建服务器,比如tomcat,jetty,mock,undertow等。

        • 10). registerListeners() #


          注册监听器,包括(静态自定的监听器|实现ApplicationListener类型的bean监听器),目前数量为0,然后通过多播器发布之前收集的事件。

        • 11). finishBeanFactoryInitialization(beanFactory) #


          初始化非懒加载单例bean对象。

        • 12). finishRefresh() #


          调用生命周期处理器的onRefresh()方法,并且发布一个ContextRefreshEvent类型事件。

    • 总结 #

  • Reference #


comments powered by Disqus