Spring源码系列(七)——Bean的实例化和初始化过程

Spring源码系列(七)——Bean的实例化和初始化过程,第1张

Spring源码系列(七)——Bean的实例化和初始化过程

https://blog.csdn.net/zxd1435513775/article/details/120935494?spm=1001.2014.3001.5501

Spring源码系列(四)——ConfigurationClassPostProcessor功能解析

https://blog.csdn.net/zxd1435513775/article/details/121113933?spm=1001.2014.3001.5501

Spring源码系列(六)——容器的刷新(下)

在第四篇和第六篇中,都分析到了一个方法,就是getBean(),这行代码的意思是:从容器中获取Bean,如果没有,则去创建Bean。所以在查看Spring源码时,只要看到这个方法,就要知道是去实例化Bean了。

这个方法的具体实现位于AbstractBeanFactory类中,下面就来分析吧。

一、getBean()

下面来看一下这个方法的详细代码:

// 根据name去获取对应的Bean实例
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

protected  T doGetBean(
    String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly){

   
    String beanName = transformedBeanName(name);
    Object bean;

   
    Object sharedInstance = getSingleton(beanName); // 此方法详解,看下面第二部分
    
    // 此处拿到sharedInstance,不为空,表示已经实例化了,但属性有没有填充不确定
    // 在分析FactoryBean的时候,分析了getObjectForBeanInstance()方法,下面我们就分析else的情况
    if (sharedInstance != null && args == null) {
       
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {

        // 判断是否是原型Bean,如果是原型,不应该在Spring容器初始化的时候创建
        // 为什么要直接抛异常呢?因为在refresh()方法中的finishBeanFactoryInitialization()方法中
        // 已经对bean进行了判断,BeanDefinition不是抽象的,不是懒加载的,是单列的才会进入执行到此处
        // 所以会抛异常
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 检查Spring工厂中是否存在bean定义
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            } else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        // 此参数为方法传入进来
        if (!typeCheckOnly) {
            // 添加到alreadyCreated set集合当中,表示他已经创建过一次
            markBeanAsCreated(beanName);
        }

        try {
            // 如果给的bean的定义是有父类的,则通过与父bean合并,返回给定顶级bean的RootBeanDefinition。
            // 在使用xml配置Bean时,有个属性parent属性来指定父类
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 再次检查,检查合并后的bean是不是抽象的
            checkMergedBeanDefinition(mbd, beanName, args);

			// 获取所依赖的bean,保证对当前bean所依赖的bean进行实例化。
            // 此处的意思是,被依赖的Bean要先进行实例化
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                    	// 抛异常代码略
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        // 又一次调用getBean()方法,此处获取的依赖bean,递归调用,获取即创建
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                    	// 抛异常代码略
                    }
                }
            }

            // 此处才开始创建Bean,也是此处进行了getSingleton()方法的第二次调用
            if (mbd.isSingleton()) {
                // 此处为getSingleton()第二次调用,两处调用,形参不一样
                // 先执行getSingleton()方法,在该方法中,可以调用lamda表达式
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 此方法看下面第四部分
                        return createBean(beanName, mbd, args);
                    } catch (BeansException ex) {
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                String scopeName = mbd.getScope();
                if (!StringUtils.hasLength(scopeName)) {
                    // 抛异常代码略
                }
                Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    // 抛异常代码略
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    // 抛异常代码略
                }
            }
        } catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                // 抛异常代码略
            }
            return convertedBean;
        } catch (TypeMismatchException ex) {
            // 抛异常代码略
        }
    }
    return (T) bean;
}
二、第一次调用getSingleton()

下面来看下这个方法详细代码:DefaultSingletonBeanRegistry类中

// 第一处getSingleton()是调用这个方法,根据beanName去singletonObjects中查询是否已经被实例化
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    
    // 从singletonObjects中获取bean,如果不为空直接返回,不再进行实例化工作
    Object singletonObject = this.singletonObjects.get(beanName);
    
    // isSingletonCurrentlyInCreation()方法判断当前beanName是不是正在创建中
    // 如果为null并且正在创建中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            
            // 去earlySingletonObjects中拿,注意这行集合里面存放的对象还没有被填充属性
            singletonObject = this.earlySingletonObjects.get(beanName);
            
            // 如果也没拿到,说明还没有创建完成
            if (singletonObject == null && allowEarlyReference) {
                
                // 去存放Bean工厂的集合里拿,看看是不是Bean工厂
                ObjectFactory singletonFactory = 
                    this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 此集合是为了解决循环引用问题
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

public boolean isSingletonCurrentlyInCreation(String beanName) {
    // 正在创建的Bean会被放到这个singletonsCurrentlyInCreation集合中
    return this.singletonsCurrentlyInCreation.contains(beanName);
}

这里要特别说一下singletonObjects,earlySingletonObjects,singletonsCurrentlyInCreation,singletonFactories四个作用,很关键!!!

  • singletonObjects是个Map,用于存放完全初始化好的 Bean,从这个Map中取出的 Bean可以直接使用
  • earlySingletonObjects是个Map,用于存放原始的Bean对象,用于解决Bean的循环依赖问题,注意:存到里面的对象还没有被填充属性,即还没有完成初始化!!!
  • singletonsCurrentlyInCreation是个Set,用于存放正在创建中的Bean
  • singletonFactories是个Map>,用于存放 Bean工厂对象,也用于解决循环依赖
三、第二次调用getSingleton()
// 第二处getSingleton()是调用这个方法,传进来的第二个参数为lamda表达式
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {

    synchronized (this.singletonObjects) {
        // 先从singletonObjects中拿取Bean
        Object singletonObject = this.singletonObjects.get(beanName);
        // 不为空的话,直接返回
        if (singletonObject == null) {
            if (this.singletonsCurrentlyInDestruction) {
            	// 抛异常代码略
            }
            
			// 将beanName添加到singletonsCurrentlyInCreation这样一个set集合中
			// 表示beanName对应的bean正在创建中
            // 创建之前把beanName放到这个singletonsCurrentlyInCreation集合中
            // 在上面第一次调用getSingleto()代码时,有个条件就是当前的beanName是不是在创建中
            beforeSingletonCreation(beanName);
            
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new linkedHashSet<>();
            }
            try {
                // 分析到此处终于要去创建对象了!!!!!
                // 此处的singletonFactory是传进来的,即为lamda表达式,去调用createBean()函数,创建Bean
                // 下面要看下第四部分
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } catch (IllegalStateException ex) {
              	// 抛异常代码略
            } finally {
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = null;
                }
                afterSingletonCreation(beanName);
            }
            // 将创建好的Bean放入singletonObjects中
            if (newSingleton) {
                // 此方法紧接着下面
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}


protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 创建好的Bean,放入到singletonObjects
        this.singletonObjects.put(beanName, singletonObject);
        // 下面这两个集合是什么时候放进去的呢?想想哦~~~~在doCreateBean()方法中
        // 从singletonFactories中移除
        // 存放 bean工厂对象解决循环依赖
        this.singletonFactories.remove(beanName);
        // 从earlySingletonObjects中移除
        // 存放原始的bean对象用于解决循环依赖,注意:存到里面的对象还没有被填充属性
        this.earlySingletonObjects.remove(beanName);
        // 创建好的Bean,放入到registeredSingletons
        this.registeredSingletons.add(beanName);
    }
}
四、createBean()

下面来看一下createBean()的详细代码:AbstractAutowireCapableBeanFactory类

// 此方法完成:创建bean实例、填充bean实例、调用后处理器等
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){

    RootBeanDefinition mbdToUse = mbd;
	// 做校验,不重要
    Class resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // 处理 lookup-method 和 replace-method 配置,Spring 将这两个配置统称为 override method
    try {
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        // 抛异常略
    }

    try {
        // 在 bean 初始化前应用后置处理,如果后置处理返回的 bean 不为空,则直接返回
        // 让 BeanPostProcessors 有机会返回一个代理而不是目标bean实例。
        // 注意下这个后置处理器:InstantiationAwareBeanPostProcessor
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    } catch (Throwable ex) {
        // 抛异常略
    }

    try {
        // 调用doCreateBean 创建bean
        // 请看下面第四部分
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        throw ex;
    } catch (Throwable ex) {
   		// 抛异常略
    }
}

五、doCreateBean()

下面来看一下doCreateBean()的详细代码:AbstractAutowireCapableBeanFactory类

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

    // 实例化bean
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
       
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    
    // 到此处,Bean实例已经创建了!!!!!
    Object bean = instanceWrapper.getWrappedInstance();
    
    Class beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // 后处理器修改合并的bean定义
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                // 抛异常略
            }
            mbd.postProcessed = true;
        }
    }

    // BeanDefinition是单例的,支持循环引用,并且正在创建
    // 看到allowCircularReferences这个属性,是不是猜想Spring可以配置是否支持循环引用呢?
    boolean earlySingletonExposure = (mbd.isSingleton() 
                            && this.allowCircularReferences 
                            && isSingletonCurrentlyInCreation(beanName));
  	
    if (earlySingletonExposure) {
        // 将正在创建的Bean放到集合中,此时Bean的属性还没赋值
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // 开始初始化Bean对象了,即属性填充
    Object exposedObject = bean;
    try {
        // 属性填充,非常重要!!!!!看第八小点
        populateBean(beanName, mbd, instanceWrapper);
        // 执行后置处理器,aop就是在这里完成的处理,看第九小点
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
		// 抛异常代码略
    }

    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set actualDependentBeans = new linkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
     				// 抛异常代码略
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
       // 抛异常代码略
    }

    return exposedObject;
}


protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            // 放到singletonFactories中
            this.singletonFactories.put(beanName, singletonFactory);
            // 在第一次调用getSingleton()方法是put
            // 移除earlySingletonObjects中
            this.earlySingletonObjects.remove(beanName);
            // 放到registeredSingletons中
            this.registeredSingletons.add(beanName);
        }
    }
}
六、createBeanInstance()
// 使用适当的实例化策略,为指定的bean创建一个新实例:工厂方法、构造函数自动装配,简单实例化。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

    // 获取BeanDefinition所转化的类Class
    Class beanClass = resolveBeanClass(mbd, beanName);

    // 检测一个类的访问权限,spring默认情况下对于非public的类是不允许访问的。
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
       // 抛异常略
    }

    Supplier instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 如果工厂方法不为空,则通过工厂方法构建 bean 对象
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

   
    // 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
	// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析

    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                // 已经解析过class的构造器
                resolved = true;
                // 如果已经解析了构造方法的参数,则必须要通过一个带参构造方法来实例
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    
    if (resolved) {
        // 已经解析过class的构造器,使用已经解析好的构造器
        if (autowireNecessary) {
            // 构造函数自动注入
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            // 通过默认的无参构造方法进行
            return instantiateBean(beanName, mbd);
        }
    }

    // 由后置处理器决定返回哪些构造方法,决定用哪个构造方法来进行实例化,此方法为选择构造函数的过程
    // 需要根据参数解析、确定构造函数
    Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_ConSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 构造函数自动注入
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // 使用默认的无参构造方法进行初始化
    return instantiateBean(beanName, mbd);
}

createBeanInstance()方法的代码逻辑如下:

  • 如果Bean定义中存在 InstanceSupplier,会使用这个回调接口创建对象,应该是3.X以后新加的,3.X的源码中没有
  • 根据配置的factoryMethodName或factory-mtehod创建Bean
  • 解析构造函数并进行实例化

因为一个类可能有多个构造函数,所以需要根据配置文件中配置的参数或者传入的参数确定最终调用的构造函数,因为判断过程会比较消耗性能,所以Spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。在下次创建相同Bean的时候,会直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析。

七、autowireConstructor()
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
                                       @Nullable Constructor[] chosenCtors, @Nullable Object[] explicitArgs) {

    // 创建一个BeanWrapperImpl 前面外部返回的BeanWrapper 其实就是这个BeanWrapperImpl
    // 因为BeanWrapper是个接口
    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    Constructor constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    // 如果getBean()中传入的参数不为空,那么就使用传入的参数
    // 确定参数值列表
    // argsToUse可以有两种办法设置
    // 第一种通过beanDefinition设置
    // 第二种通过xml设置
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    } else {
        // 否则就需要解析配置文件中的参数
        Object[] argsToResolve = null;
        synchronized (mbd.constructorArgumentLock) {
            // 获取已解析的构造方法,一般不会有,因为构造方法一般会提供一个
            // 除非有多个,那么才会存在已经解析完成的构造方法
            constructorToUse = (Constructor) mbd.resolvedConstructorOrFactoryMethod;
            
            if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                // 在缓存中找到了构造器,就继续从缓存中寻找缓存的构造器参数
                argsToUse = mbd.resolvedConstructorArguments;
                if (argsToUse == null) {
                    // 没有缓存的参数,就需要获取配置文件中配置的参数
                    argsToResolve = mbd.preparedConstructorArguments;
                }
            }
        }
        // 如果缓存中没有缓存的参数的话,即argsToResolve不为空,就需要解析配置的参数
        if (argsToResolve != null) {
            // 解析参数类型,比如将配置的String类型转换成int、boolean等类型
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
        }
    }

    // 如果没有缓存,就需要从构造函数开始解析
    if (constructorToUse == null) {
        // 如果没有已经解析的构造方法,则需要去解析构造方法
        // 判断构造方法是否为空,判断是否根据构造方法自动注入
        boolean autowiring = (chosenCtors != null ||
                              mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        // 定义了最小参数个数
        // 如果你给构造方法的参数列表给定了具体的值
        // 那么这些值的个数就是构造方法参数的个数
        int minNrOfArgs;
        if (explicitArgs != null) {
            // getBean方法传入的参数
            minNrOfArgs = explicitArgs.length;
        } else {
            // 配置文件中的配置的参数
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            // 用于承载解析后的构造函数参数的值
            resolvedValues = new ConstructorArgumentValues();
            
            // 解析配置文件中的参数,并且返回参数个数
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        // 如果传入的构造器数组不为空,就使用传入的构造器参数,否则通过反射获取class中定义的构造器
        Constructor[] candidates = chosenCtors;
        if (candidates == null) {
            Class beanClass = mbd.getBeanClass();
            try {
                // 使用public的构造器或者所有构造器
                candidates = (mbd.isNonPublicAccessAllowed() ?
                              beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }
        }
        // 根据构造方法的访问权限级别和参数数量进行排序
        // 怎么排序的呢?
        
        // 给构造函数排序,public构造函数优先、参数数量降序排序
        AutowireUtils.sortConstructors(candidates);
        //定义了一个差异变量,这个变量很有分量,后面有注释
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set> ambiguousConstructors = null;
        linkedList causes = null;

        //循环所有的构造方法
        for (Constructor candidate : candidates) {
            Class[] paramTypes = candidate.getParameterTypes();

           
            if (constructorToUse != null && argsToUse.length > paramTypes.length) {
                break;
            }
            if (paramTypes.length < minNrOfArgs) {
                continue;
            }

            // 封装解析到的参数信息
            ArgumentsHolder argsHolder;
            if (resolvedValues != null) {
                try {
                    // 判断是否加了ConstructorProperties注解如果加了则把值取出来
                    // 可以写个代码测试一下
                    // @ConstructorProperties(value = {"xxx", "111"})
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                    if (paramNames == null) {
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            //获取构造方法参数名称列表
                            
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    // 获取构造方法参数值列表
                    
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                                                     getUserDeclaredConstructor(candidate), autowiring);
                }
            } else {
                // Explicit arguments given -> arguments length must match exactly.
                if (paramTypes.length != explicitArgs.length) {
                    continue;
                }
                argsHolder = new ArgumentsHolder(explicitArgs);
            }
            
            // 因为不同构造函数的参数个数相同,而且参数类型为父子关系,所以需要找出类型最符合的一个构造函数
			//Spring用一种权重的形式来表示类型差异程度,差异权重越小越优先
            int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                                  argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
            // 当前构造函数最为匹配的话,清空先前ambiguousConstructors列表
            if (typeDiffWeight < minTypeDiffWeight) {
                constructorToUse = candidate;
                argsHolderToUse = argsHolder;
                argsToUse = argsHolder.arguments;
                minTypeDiffWeight = typeDiffWeight;
                ambiguousConstructors = null;
            } else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                // 存在相同权重的构造器,将构造器添加到一个ambiguousConstructors列表变量中
				// 注意,这时候constructorToUse 指向的仍是第一个匹配的构造函数
                if (ambiguousConstructors == null) {
                    ambiguousConstructors = new linkedHashSet<>();
                    ambiguousConstructors.add(constructorToUse);
                }
                ambiguousConstructors.add(candidate);
            }
        }
        // 循环结束,没有找打合适的构造方法
        if (constructorToUse == null) {
			//如果没有匹配的构造函数,抛出异常。略
        }
        // 如果ambiguousConstructors还存在则异常?为什么会在上面方法中直接exception?
        // 上面注释当中有说明
        else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
         // 如果存在多个构造函数匹配程度相同,并且BeanDefinition中设置isLenientConstructorResolution为false(默认值为true),
		 // 表示构造器创建为严格模式的话,会抛出异常。异常代码略
        }

        // 这一步就是将解析好的构造函数放入缓存resolvedConstructorOrFactoryMethod,如果需要的话也会缓存参数
		// 并设置constructorArgumentsResolved为true,表示已经解析过构造函数
        if (explicitArgs == null) {
            
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    try {
		// 使用反射创建实例 lookup-method 通过CGLIB增强bean实例
        final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
        Object beanInstance;

        if (System.getSecurityManager() != null) {
            final Constructor ctorToUse = constructorToUse;
            final Object[] argumentsToUse = argsToUse;
            beanInstance = AccessController.doPrivileged((PrivilegedAction) () ->
                                                         strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
                                                         beanFactory.getAccessControlContext());
        } else {
            beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
        }

        bw.setBeanInstance(beanInstance);
        return bw;
    }
}
 

autowireConstructor()这个方法代码非常长,总体的功能逻辑如下

  • 确定参数
    • 如果调用getBean()方法时传入的参数不为空,则可以直接使用传入的参数
    • 再尝试从缓存中获取参数
    • 否则,需要解析节点配置的构造器参数
  • 确定构造函数。根据第一步中确定下来的参数,接下来的任务就是根据参数的个数、类型来确定最终调用的构造函数。首先是根据参数个数匹配,把所有构造函数根据参数个数升序排序,再去筛选参数个数匹配的构造函数,因为配置文件中可以通过参数位置索引,也可以通过参数名称来设定参数值,如,所以还需要解析参数的名称。最后,根据解析好的参数名称、参数类型、实际参数就可以确定构造函数,并且将参数转换成对应的类型
  • 根据确定的构造函数转换成对应的参数类型
  • 构造函数不确定性的验证。因为有一些构造函数的参数类型为父子关系,所以Spring会做一次验证
  • 如果条件符合(传入参数为空),将解析好的构造函数、参数放入缓存
  • 根据实例化策略将构造函数、参数实例化Bean

这个方法就是为了找到最合适的构造函数来实例化Bean,需要来确定构造函数的参数个数。

八、populateBean()
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
			// 抛异常略
        } else {
            // 空对象直接返回
            return;
        }
    }

    // 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
	// 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }

    // pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写 *** 作实现,同时可以通过调用构造函数实现深拷贝
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
    // 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        // 深拷贝当前已有的配置
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        
        // 根据名称进行注入
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        
        // 根据类型进行注入
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        // 结合注入后的配置,覆盖当前配置
        pvs = newPvs;
    }
	// 容器是否注册了InstantiationAwareBeanPostProcessor
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否进行依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    if (hasInstAwareBpps || needsDepCheck) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        // 过滤出所有需要进行依赖检查的属性编辑器
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                // 如果有相关的后置处理器,进行后置处理
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            // 检查是否满足相关依赖关系,对应的depends-on属性,需要确保所有依赖的Bean先完成初始化
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }

    if (pvs != null) {
         // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

Spring的装配问题:

public static final int AUTOWIRE_NO = 0;
public static final int AUTOWIRE_BY_NAME = 1;
public static final int AUTOWIRE_BY_TYPE = 2;
public static final int AUTOWIRE_ConSTRUCTOR = 3;

Spring默认的装配类型是AUTOWIRE_NO,表示不默认装配,除非你在代码中手动添加@Autowired、@Resouce等注解手动注入
AUTOWIRE_BY_TYPE表示为按类型装配,在实例化类的时候是根据属性是否具有set方法,如果有,则进行装配

九、initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 权限校验
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor的postProcessBeforeInitialization()方法
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 调用初始化方法,先执行实现InitializingBean接口的方法,再执行自定义的init-method方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
       // 抛异常略
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 调用BeanPostProcessor的postProcessAfterInitialization()方法
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
 
十. invokeInitMethods() 
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

    // 是不是实现了InitializingBean
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            } catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        } else {
            // 调用afterPropertiesSet()方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        // 是不是有自定义的init-method方法
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 执行自定义的init-method方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
 
十一、小结 

以上的getBea()方法终于分析完了,其中doCreateBean()方法比较重要吧,要重点看一下,autowireConstructor()方法比较难理解,但知道它的作用是什么就好了.

下面来用一张图总结一下这个过程吧。

上图中,红蓝色的框表示的循环依赖的问题,此处简单描述一下。

X和Y相互依赖,先实例化X,在实例化X的过程中会发现X依赖了Y,于是就去实例化Y,就是图中的红色虚线

在实例化Y的过程中,发现Y又依赖于X,但此时的X正在创建,被保存在singletonFactories中,所以就把singletonFactories中的X赋值给了Y,这样Y的依赖就解决了,所以Y的实例化就结束了,就会把Y正常返回

下面就继续实例化X的流程了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5078741.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-16
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)