Spring源码解析-bean加载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012006689/article/details/80213830

本文介绍bean加载,对应代码:

Cat cat = (Cat) bf.getBean("testCat");

Spring对这行代码的具体实现大致步骤如下:

1. 转换beanName

为什么需要转换beanName?因为传入的参数name不一定是真实的beanName,可能是alias,也可能是FactoryBean,所以需要:

  • 去除FactoryBean的修饰符,就是说如果name=“&aa”,那么先去除&使name=“aa”。因为想获取FactoryBean的实例时,需要在beanName前面加“&”。
  • 取指定alias所表示的beanName,例如alias A指向alias B,alias B又指向名称为C的Bean,最终应返回C;

2. 尝试从缓存中加载单例

单例在Spring的同一个容器内只会被创建一次,后续再获取bean,就直接从单例缓存中获取了。

3. bean的实例化

如果从缓存中取到了的bean的原始状态,则需要对bean进行实例化。缓存中记录的是最原始的bean状态,不一定是我们最终想要的bean。举个例子,比如从缓存中获得的是工厂bean的初始状态,我们真正需要的是factory-method方法中返回的bean。

4. GenericBeanDefinition转换为RootBeanDefinition

从XML配置文件中读取到的Bean信息是存储在GenericBeanDefinition中的,但是所有的Bean后续处理都是针对于RootBeanDefinition的,所以需要转换。

5. 寻找依赖

在Spring的加载顺序中,在初始化某一个bean的时候,首先会初始化这个bean所对应的依赖。

6. 针对不同scope进行bean的创建

bean scope可以是prototype、request、singleton等,Spring在这个步骤根据不同的scope进行不同的初始化策略。

7. 类型转换

将返回的bean转换为requiredType指定的类型。


选最重要的第6步细说。
常规bean的创建在AbstractAutowireCapableBeanFactory的doCreateBean方法中。为了能够体现主要逻辑,去除日志、异常的处理、循环依赖的处理:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 如果是单例,首先清除缓存
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }

    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            //应用MergedBeanDefinitionProcessor
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }

    // Initialize the bean instance.
    Object exposedObject = bean;

    //对bean进行填充,将各个属性注入
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }

    // Register bean as disposable.
    registerDisposableBeanIfNecessary(beanName, bean, mbd);

    return exposedObject;
}

步骤很清晰:
1. 如果是单例,首先清除缓存;
2. 实例化bean,将BeanDefinition转换为BeanWrapper;
实例化bean的策略有:

  • 如果存在工厂方法,则使用工厂方法进行初始化
  • 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化;
  • 如果既不存在工厂方法,也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化;

3.属性填充,将所有属性填充到bean的实例中;
4.注册DisposableBean
如果配置了destroy-method方法,这里需要注册以便于在销毁时候使用。

进一步来解析第2步和第三步。


创建Bean实例

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // Make sure bean class is actually resolved at this point.
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        // 如果工厂方法不为空则使用工厂方法初始化策略
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // 需要根据参数解析构造函数
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        //使用默认构造函数构造
        return instantiateBean(beanName, mbd);
    }

1.如果RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod方法根据RootBeanDefiniton中的配置生成bean的实例。

2.解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。

3.如果需要使用构造函数实例化,那么就根据实例化策略、得到的构造函数、以及构造函数的参数(BeanDefinition中)实例化bean;如果是使用默认的构造函数实例化,就直接调用实例化策略进行实例化。

实例化策略

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
    // 如果有需要覆盖或者动态替换的方法,需要使用cglib进行动态代理;因为动态可以在创建代理的同时将动态方法织入类中;
    //如果没有动态需要改变的方法,直接反射就可以了
    if (beanDefinition.getMethodOverrides().isEmpty()) {
        Constructor<?> constructorToUse;
        synchronized (beanDefinition.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = beanDefinition.getBeanClass();
                constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
            }
        }
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        return instantiateWithMethodInjection(beanDefinition, beanName, owner);
    }
}

BeanUtils的instantiateClass方法:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args)  {
    ReflectionUtils.makeAccessible(ctor);
    return ctor.newInstance(args);
}

属性注入

属性注入发生在AbstractAutowireCapableBeanFactory的populateBean方法。
这个方法中有两个需要关注的点:
1.当bean配置了autowire属性,那么会根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中;
2.将所有PropertyValues中的属性填充至BeanWrapper中;

  • byName
    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

        //寻找bw中需要依赖注入的属性
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);

        for (String propertyName : propertyNames) {
            if (containsBean(propertyName)) {
                // 使用当前Bean的属性名作为Bean的名字,向IOC容器索取Bean,然后把从IOC容器中取到的Bean,设置到当前Bean的属性中去;
                //递归初始化相关bean
                Object bean = getBean(propertyName);
                pvs.add(propertyName, bean);
                registerDependentBean(propertyName, beanName);
            }
        }
    }

对于autowireByName,首先通过反射机制从当前Bean中得到需要注入的属性名,然后使用这个属性名向Spring容器申请与之同名的Bean,这样实际又触发了另一个Bean的生成和依赖注入的过程。

  • autowireByType
    首先也是寻找bw(BeanWrapper )需要依赖注入的属性,然后遍历这些属性寻找类型匹配的bean。

  • applyPropertyValues

获取的属性以PropertyValues形式存在,还没有应用到实例化bean中,这一工作在AbstractAutowireCapableBeanFactory中。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {


    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        if (mpvs.isConverted()) {
            // 如果mpvs中的值已经被转换为对应的类型,那么可以直接设置到beanwrapper中
            bw.setPropertyValues(mpvs);
            return;
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        // 如果mpvs不是MutablePropertyValues封装的类型,直接使用原始的属性获取
        original = Arrays.asList(pvs.getPropertyValues());
    }

    // 获取对应的解析器
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    //遍历属性,将属性转换为对应类的对应属性的类型
    for (PropertyValue pv : original) {
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                    !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                    !((TypedStringValue) originalValue).isDynamic() &&
                    !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }

    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}

猜你喜欢

转载自blog.csdn.net/u012006689/article/details/80213830