Spring的初始化和对象创建流程

Spring容器的初始化和对象创建流程(代码方面):
如图:
1.Spring容器初始化流程:
Spring的初始化和对象创建流程_第1张图片
文字说明:

  1. 在ClassPathXmlApplicationContext的构造函数中:
    super(parent);//调用父级的构造方法,构造父类对象和初始化相关属性,供子类使用。
    setConfigLocations(configLocations);该方法会对资源路径实现相关处理:
    比如,若资源路径中含有Spring-${username}.xml,资源占位符时,该方法就会对资源路径实现替换和赋值操作。
  2. prepareRefresh():设置启动日期,设置容器的关闭状态为false,活跃状态为true,以及执行属性源的任何初始化。
  3. obtainFreshBeanFactory():这里使用了委派设计模式,父类定义了抽象的refreshBeanFactory()方法, 具体实现调用子类容器的refreshBeanFactory()方法,作用:若已经存在beanFactory,则销毁,创建新的工厂DefaultListableBeanFactory,调用载入Bean定义的方法:loadBeanDefinitions(beanFactory);,主要这里又使用了一个委派模式,具体的实现调用子类容器的。
  4. prepareBeanFactory(beanFactory):该方法内部都是一些set、add、register方法,所有该方法是配置工厂的相关属性,例如上下文的ClassLoader和后处理器。
  5. postProcessBeanFactory(beanFactory);该方法点进去发现是一个空方法,由子类实现可实现指定特殊的BeanPost事件处理器。
  6. invokeBeanFactoryPostProcessors(beanFactory);调用所有注册的BeanFactoryPostProcessor的Bean。
  7. finishBeanFactoryInitialization(beanFactory);完成此上下文的bean工厂的初始化,初始化所有剩余的单例bean,该方法开实例化对象。

2.Spring创建对象流程:
Spring的初始化和对象创建流程_第2张图片

文字说明:

  1. beanFactory.preInstantiateSingletons()方法说明:
    该方法所在的类DefaultListableBeanFactory就是bean工厂,对未配置lazy-init属性的单态模式Bean进行预实例化处理
    1.1 从bean工厂中获取bean定义名称集合
    List beanNames = new ArrayList<>(this.beanDefinitionNames);

    1.2 遍历bean名称集合,根据beanName获取合并的rootBeanDefinition: RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

    1.3 根据获取到的bd(bean的定义信息),判断,若当前bean不是抽象类、不是懒加载、并且是bean的作用域为单例,则 调用getBean方法,触发容器对Bean实例化和依赖注入过程:getBean(beanName);否则,不做处理;

    1.4 触发所有适用bean的初始化后回调: 遍历beanName集合,根据beanName,从缓存中获取对应的bean实例 Object singletonInstance = getSingleton(beanName);
    判断获取到的bean是否实现了SmartInitializingSingleton接口,若实现了则转换类型,去调用afterSingletonsInstantiated()方法.

  2. getBean()方法说明:
    2.1 String beanName = transformedBeanName(name);提取对应的beanName
    2.2 从缓存中获取对应的名称的bean对象:
    Object sharedInstance = getSingleton(beanName);
    若缓存中存在 则调用: bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    获取给定bean实例的对象,或者是bean实例本身或它创建的对象(在FactoryBean的情况下):
    若缓存中不存在:
    获取分类工厂对象,若当前容器的父级容器存在,且当前容器中不存在指定名称的Bean,则判断parentBeanFactory是否是AbstractBeanFactory的子类,若是,则((AbstractBeanFactory)
    parentBeanFactory).doGetBean();重新调用doGetBean方法;若不是,则委派父级容器根据相关参数去查找,
    2.3 String[] dependsOn = mbd.getDependsOn();获取bean定义信息中设置depends-on属性,保证初始化当前bean所依
    赖的bean; 若存在dependsOn属性值,遍历数据,则把被依赖Bean注册给当前依赖的Bean,
    registerDependentBean(dep,beanName);递归调用getBean方法,
    获取当前Bean的依赖Bean:getBean(dep);
    2.4 获取注册在给定名称下的(原始)单例对象,如果没有则使用lambda创建对象;
    sharedInstance = getSingleton(beanName, () -> {
    try {
    //缓存中不存在对应bean的实例,开始创建对象
    return createBean(beanName, mbd, args);
    }
    该方法内部:首先从一级缓存中获取对应的bean:
    Object singletonObject = this.singletonObjects.get(beanName);
    若存在,则直接返回对象,若不存在,则:
    创建单例之前的回调: 将要创建的bean对象加入到正在创建的bean的集合中
    beforeSingletonCreation(beanName);
    这里使用lambda表达式方式,调用createBean(beanName, mbd, args)方法创建对象
    singletonObject = singletonFactory.getObject();
    单例创建后的回调:将beanName从正在创建的bean的集合中移除
    afterSingletonCreation(beanName);

  3. doCreateBean方法说明
    3.1 instanceWrapper = createBeanInstance(beanName, mbd, args);使用反射的方式获取bean的实例;
    3.2 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    这里将对象信息和该对象的工厂,放入到三级缓存中,下次获取时直接获取到指定工厂来创建对象,作用:为了防止循环引用,尽早持有对象的引用。
    3.3 populateBean(beanName, mbd, instanceWrapper);这个方法会完成属性的填充,里面会涉及到引用类型的属性填充,该方法内部会实现对引用类型的属性进行解析,解析后获取到对应的属性名,然后根据属性名调用bean = this.beanFactory.getBean(refName);则会递归触发引用Bean的初始化和依赖注入:getBean–>doGetBean…最终会获取到目的属性引用的对象,填充到当前的对象属性中。
    3.4 exposedObject = initializeBean(beanName, exposedObject, mbd);该方法内部:
    调用实现了aware接口需要实现的方法:invokeAwareMethods(beanName, bean);
    执行BeanPostProcessorsBefore实现前置处理
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    执行初始化方法:invokeInitMethods(beanName, wrappedBean, mbd);
    执行BeanPostProcessorsAfterInitialization实现后置处理
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

你可能感兴趣的:(Spring源码)