美文网首页
从宏观角度分析Spring源码之DI

从宏观角度分析Spring源码之DI

作者: 皮__皮卡丘 | 来源:发表于2020-05-08 09:57 被阅读0次

        上篇文章讲解了IOC容器的初始化,将所有需要加载的Bean的定义(BeanDefinition)放入到了beanDefinitionMap中以等待后续的实例化和依赖注入。翻过源码的铁子们一定知道Bean的实例化和依赖注入过程的调用链非常繁杂,为了便于理解,将抛弃Spring框架中对细节的处理,从源码中抽取一条鲜明且具有代表性的主线进行分析。

    1、概念

        DI的全称是Dependency Injection,即依赖注入。通俗点来说,在A对象被创建的时候,由容器动态地将A所依赖的其他对象的引用注入进来。例如:Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过容器控制程序来将B对象在外部new出来并注入到A类里的引用中。

    2、DI流程描述

      依赖注入主要有两大步骤来实现:

    (1)Bean的实例化

    (2)Bean属性的依赖注入

    3、DI源码分析

        首先要明确一点,依赖注入的过程是第一次调用getBean()方法的时候触发的,但是,如果设置了lazy-init属性为false,依赖注入的过程会由IOC容器直接完成。

        废话少说,直接上时序图:

        通过时序图能清晰地看到依赖注入的整个调用流程, 一般情况下我们会通过ApplicationContext来调用getBean()方法,然而打开源码一看getBean()方法是由ApplicationContext的父接口BeanFactory定义的,这就是依赖注入发生的起点。在整个调用链条中,依赖注入最主要的两个方法是createBeanInstance()和populateBean(),下面着重分析下这两个方法。

        在createBeanInstance()方法中对Bean进行了实例化,即生成了Bean的对象,这个Bean实例的生成有不同的方式,可以通过工厂模式生成,也可以构造函数生成,采用哪种生成方式是由BeanDefinition来决定的。来看下createBeanInstance()的源码:

    ```

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

    // Make sure bean class is actually resolved at this point.

    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

    throw new BeanCreationException(mbd.getResourceDescription(), beanName,

    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();

    if (instanceSupplier != null) {

    return obtainFromSupplier(instanceSupplier, beanName);

    }

            //使用工厂方法对Bean进行实例化

    if (mbd.getFactoryMethodName() != null) {

    return instantiateUsingFactoryMethod(beanName, mbd, args);

    }

    // Shortcut when re-creating the same bean...

    boolean resolved = false;

    boolean autowireNecessary = false;

    if (args == null) {

    synchronized (mbd.constructorArgumentLock) {

    if (mbd.resolvedConstructorOrFactoryMethod != null) {

    resolved = true;

    autowireNecessary = mbd.constructorArgumentsResolved;

    }

    }

    }

            //使用构造函数进行实例化

    if (resolved) {

    if (autowireNecessary) {

    return autowireConstructor(beanName, mbd, null, null);

    }

    else {

    return instantiateBean(beanName, mbd);

    }

    }

    // Candidate constructors for autowiring?

    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||

    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

    return autowireConstructor(beanName, mbd, ctors, args);

    }

    // Preferred constructors for default construction?

    ctors = mbd.getPreferredConstructors();

    if (ctors != null) {

    return autowireConstructor(beanName, mbd, ctors, null);

    }

    // No special handling: simply use no-arg constructor.

    return instantiateBean(beanName, mbd);

    }

    ```

    而最常用的实例化方法是通过 instantiateBean()来完成的,如下:

    ```

    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

    try {

    Object beanInstance;

    final BeanFactory parent = this;

    if (System.getSecurityManager() != null) {

    beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->

    getInstantiationStrategy().instantiate(mbd, beanName, parent),

    getAccessControlContext());

    }

    else {

    beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

    }

    BeanWrapper bw = new BeanWrapperImpl(beanInstance);

    initBeanWrapper(bw);

    return bw;

    }

    catch (Throwable ex) {

    throw new BeanCreationException(

    mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

    }

    }

    ```

        使用默认的策略对Bean进行实例化,查看源码可以发现,默认实例化策略是使用CGLIB动态代理对Bean进行实例化的。

    ```

    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory

    implements AutowireCapableBeanFactory {

    /** Strategy for creating bean instances. */

    private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

    ```

        通过createBeanInstance()方法的调用完成了Bean的实例化过程,在实例化结束后还需要将Bean对象的依赖关系设置好,才能完成整个依赖注入过程,接下来分析依赖注入方法populateBean(),该方法在AbstractAutowireCapableBeanFactory中,源码如下: 

    ```

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

    if (bw == null) {

    if (mbd.hasPropertyValues()) {

    throw new BeanCreationException(

    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

    }

    else {

    // Skip property population phase for null instance.

    return;

    }

    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the

    // state of the bean before properties are set. This can be used, for example,

    // to support styles of field injection.

    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

    for (BeanPostProcessor bp : getBeanPostProcessors()) {

    if (bp instanceof InstantiationAwareBeanPostProcessor) {

    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

    return;

    }

    }

    }

    }

                //获取beanDefinition中设置的property值

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();

                //开始依赖注入

    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

    MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

    // Add property values based on autowire by name if applicable.

                    //根据name进行注入

    if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

    autowireByName(beanName, mbd, bw, newPvs);

    }

    // Add property values based on autowire by type if applicable.

                    //根据type进行注入

    if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

    autowireByType(beanName, mbd, bw, newPvs);

    }

    pvs = newPvs;

    }

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;

    if (hasInstAwareBpps) {

    if (pvs == null) {

    pvs = mbd.getPropertyValues();

    }

    for (BeanPostProcessor bp : getBeanPostProcessors()) {

    if (bp instanceof InstantiationAwareBeanPostProcessor) {

    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

    if (pvsToUse == null) {

    if (filteredPds == null) {

    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

    }

    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

    if (pvsToUse == null) {

    return;

    }

    }

    pvs = pvsToUse;

    }

    }

    }

    if (needsDepCheck) {

    if (filteredPds == null) {

    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

    }

    checkDependencies(beanName, mbd, filteredPds, pvs);

    }

    if (pvs != null) {

                    //对属性进行注入

    applyPropertyValues(beanName, mbd, bw, pvs);

    }

    }

    ```

        通过源码可以看到依赖注入方式有name注入和type注入两种方式,最后调用applyPropertyValues(beanName, mbd, bw, pvs)方法对Bean依赖的属性进行赋值,至此完成依赖注入过程。

        由于是站在宏观的角度来分析Spring的源码,主要是把握主线思路,细节是不做讲解的,如有需要可以留言进行讨论。下篇文章将对Spring的AOP源码实现进行分析!

    此文章原地址:https://blog.csdn.net/qq_27324761/article/details/105940919

    相关文章

      网友评论

          本文标题:从宏观角度分析Spring源码之DI

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