美文网首页
4、spring初始化过程

4、spring初始化过程

作者: lois想当大佬 | 来源:发表于2020-04-22 20:56 被阅读0次

spring初始化过程也叫ioc容器初始化过程、bean生命周期。

1、从main函数开始

  public static void main(String[] args) {
        // 创建 ioc 容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取 bean
        User user = (User) context.getBean("user");
        user.test();
    }

2、进入new ClassPathXmlApplicationContex()构造方法,看ioc容器的创建过程

  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(parent);
        // 获取xml文件并存储到String[] configLocations中
        this.setConfigLocations(configLocations);
        if (refresh) {
            // 重点方法,功能较复杂,继续往下看
            this.refresh();
        }
    }

3、进入AbstractRefreshableConfigApplicationContext类的this.setConfigLocations()方法,可以看到参数locations的内容如下图

xml文件

把参数location解析完路径后放入string[] configLocations中,如下图

解析xml路径并存储起来

返回上一层ClassPathXmlApplicationContext构造方法

4、进入AbstractApplicationContext类的this.refresh()方法,该方法是重点

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

4.1、进入this.prepareRefresh()方法


image.png

看看this.getEnvironment()内容,jdk环境信息和转换器


image.png

继续看validateRequiredProperties()方法


image.png

继续进入AbstractPropertyResolver.validateRequiredProperties()


image.png
image.png

至此,this.prepareRefresh()方法解析完毕,总结下它的作用:
\color{red}{1、判断系统要求的属性如果不存在,则抛出异常,终止加载流程。}

4.2、进入this.obtainFreshBeanFactory()方法


image.png

方法this.refreshBeanFactory()是重点,进入


image.png

创建DefaultListableBeanFactory对象,可以理解为就是ApplicationContext


image.png

方法this.loadBeanDefinitions(beanFactory)是重点,进入


image.png

创建XmlBeanDefinitionReader对象,用于解析xml文件中定义的bean


image.png

方法this.loadBeanDefinitions(beanDefinitionReader)是重点,进入


image.png

接下来是bean解析和保存的过程,一路进入到AbstractBeanDefinitionReader.loadBeanDefinitions(String location, Set<Resource> actualResources)方法


image.png

拿到resource[xml文件],进入this.loadBeanDefinitions(resources)方法,一路往下走,最终又会进入XmlBeanDefinitionReader.(EncodedResource encodedResource)方法


image.png

进入this.doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法,把resource解析为doc


image.png

进入this.registerBeanDefinitions(doc, resource)方法


image.png

进入documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource))方法


image.png

进入this.doRegisterBeanDefinitions(root)方法


image.png

进入this.parseBeanDefinitions(root, this.delegate)方法


image.png

进入this.parseDefaultElement(ele, delegate)方法


image.png

进入this.processBeanDefinition(ele, delegate)方法,将xml中的bean信息解析封装为BeanDefinition对象


image.png

进入BeanDefinitionReaderUtils.registerBeanDefinition()方法,将BeanDefinition对象注册到BeanFactory中


image.png

至此this.obtainFreshBeanFactory()方法方法解析完毕,总结它的作用:
\color{#FF0000}{1.实例化了一个DefaultListableBeanFactory对象,}
\color{#FF0000}{即创建bean工厂applicationContext.}

\color{#FF0000}{2.实例化了一个XmlBeanDefinitionReader对象,解析xml配置文件,}
\color{#FF0000}{将xml中的bean信息解析封装为BeanDefinition对象.}

\color{red}{3.通过一个工具类将解析好的BeanDefinition对象注册到BeanFactory中,}
\color{red}{以key - value 的形式保存在BeanFactory中,其中key为beanName.}

4.3、进入this.prepareBeanFactory(beanFactory)方法


image.png

该方法作用,主要给beanFactory设置相关属性:
1、类加载器、类表达式解析器、属性编辑注册器
2、添加bean后处理器等
3、资源注册
4、注册默认的environment beans

4.4、this.postProcessBeanFactory(beanFactory)不用关注。

4.5、进入this.invokeBeanFactoryPostProcessors(beanFactory)方法

调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors


image.png

调用实现Ordered的BeanDefinitionRegistryPostProcessors


image.png

总结该方法作用:
\color{red}{1、查询当前在BeanFactory中是否有指定类型的Bean信息,}
\color{red}{如果有则获取Bean实体并执行相关方法.}

4.6、进入this.registerBeanPostProcessors(beanFactory)方法


image.png

BeanPostProcessor与BeanFactoryPostProcessor很类似,也是存在优先级的,但BeanPostProcessor在处理完之后,并没有立即调用processor的方法,而是将一系列的BeanPostProcessor实体对象注册到BeanFactory中。在后面的初始化过程中会使用到这些Processor。

总结该方法作用:
\color{red}{1、查询当前在BeanFactory中是否有指定类型的Bean信息,}
\color{red}{如果有则将Bean实体注册到beanFactory中.}

4.7、 方法initMessageSource()是空方法,不用关注
4.8、进入initApplicationEventMulticaster()方法


image.png

总共该方法作用:
\color{red}{1、判断bean工厂是否包含应用事件广播器,没有的话,创建一个,}
\color{red}{然后,把它放入bean工厂中。}

4.9、方法this.onRefresh()是空方法,不用关注
4.10、进入this.registerListeners()方法


image.png

总结该方法作用:
\color{red}{1、把bean工厂下的监听器添加到应用广播器中,在事件触发的时候可回调监听器中的方法。}

4.11、进入this.finishBeanFactoryInitialization(beanFactory)方法,该方法也是重点
该方法调用过程:【数据来源顶部链接】

org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization()
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons()
org.springframework.beans.factory.support.AbstractBeanFactory.getBean()
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean()
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton()
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$0(AbstractBeanFactory.java:312)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance()
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean()
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate()
org.springframework.beans.BeanUtils.instantiateClass()

这个方法就是实例化beanFactory中的BeanDefinition,该方法解决了bean循环引入问题,具体分析放到下次更新。

4.12、方法this.finishRefresh()暂不介绍。

5、总结spring初始化重要的8个方法:

this.prepareRefresh();
this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initApplicationEventMulticaster();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);

spring初始化过程到此结束。如果错漏地方,望指出!!!

相关文章

  • 4、spring初始化过程

    spring初始化过程也叫ioc容器初始化过程、bean生命周期。 1、从main函数开始 2、进入new Cla...

  • spring-容器1-概览

    spring-容器2-初始化1spring-容器3-初始化2spring-容器4-初始化完成spring-容器5-...

  • Spring IoC一、容器初始化过程

    Spring IoC一、容器初始化过程 本文追踪Spring运行程序流程分析Ioc容器初始化的过程。依赖注入的部分...

  • Spring中IOC容器的初始化过程

    Spring IOC容器初始化过程分为Resource定位,载入解析,注册。IOC容器初始化过程中不包含Bean的...

  • Spring IOC核心源码学习

    1. 初始化 大致单步跟了下Spring IOC的初始化过程,整个脉络很庞大,初始化的过程主要就是读取XML资源,...

  • 获取ApplicationContext

    SpringApplicationContext是Spring的一个容器,在Spring初始化的过程中,Sprin...

  • Spring: 初始化过程

    Spring IoC容器的初始化是由AbstractApplicationContext的refresh()来启动的。

  • spring bean

    Spring IOC 容器源码分析 Bean初始化过程 ConversionService ConversionS...

  • Spring Boot Web容器初始化方式

    Spring Boot容器另类的初始化过程 对于Spring Boot应用来说,它并未使用SpringServle...

  • 我们从ClassPathXmlApplicationContext类的构造方法开始,学习spring初始化过程; ...

网友评论

      本文标题:4、spring初始化过程

      本文链接:https://www.haomeiwen.com/subject/mkakihtx.html