欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

深入理解Spring IOC(六)、 bean的填充以及初始化工作

如果你已经看到了这里并且把之前的都看明白了,那么恭喜你,最难的地方你已经搞定了。现在在整个spring ioc的流程中,对你来说应该不会再有太难的了,同时再去看spring的其他模块的源码,也相对会容易一些,尤其是其他框架和Spring整合的代码。如果没有看懂的也别着急,你可以把本篇看完,然后回过头去再去看之前的,源码也很少有人一遍就能看明白,我自己看这块的源码也是看了很多遍以及debug了很多遍才明白的。

真的需要你的一个赞来鼓励一下,因为写这种源码解析真的太太太太不容易了,谁写谁知道。

回到正题,我们上一篇主要说了doCreateBean中的createBeaninstance这个方法,这个方法为我们创建了未被填充的bean实例,本篇我们来看已经创建出来的bean实例是怎样被填充以及初始化的。

我们回到doCreateBean方法中,我再把这个方法代码贴一下,其中,1处上篇已经讲过,我们直接来看第2处

                                        代码块1

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

    // BeanWrapper是bean的包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 从正在创建的factoryBean的缓存中移除(准确说其实是去拿,同时移除)
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 1. 如果到这里是null,则去创建一个包含着bean实例的instanceWrapper
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
    Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

    // 使用MergedBeanDefinitionPostProcessor修改RootBeanDefinition
    // 主要是处理@Autowired 、 @inject 、@value 标着的方法和属性
    // 从这里往后,spring 才知道是哪个方法或者是属性有这个注解
    // 这里的具体的代码解析不再贴出来(因为不是重点),在我第一篇的github上面你也可以自己下载源码来看,里面都有注释
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            mbd.postProcessed = true;
        }
    }

    // earlySingletonExposure是判断是否要提前曝光这个半成品的实例的,注意哈:现在的bean只是个半成品
    // 因为还没有进行属性填充,以及执行初始化方法等操作
    // mbd是单例 && 允许循环引用(默认true) && 当前bean是不是正在创建中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isDebugEnabled()) {
            logger.debug("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        // 提前曝光这个beanName对应的ObjectFactory,用来解决循环引用
        addSingletonFactory(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                // 2.使用SmartInstantiationAwareBeanPostProcessor返回早期bean的半成品时的引用
                // 如果没有SmartInstantiationAwareBeanPostProcessor,则直接返回bean
                // 这里返回的最终是bean本身
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }

    // 初始化
    Object exposedObject = bean;
    try {
        // 3. 对bean进行属性填充
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            // 4. 初始化操作
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
    }catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        }else {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

    // 如果需要提前曝光半成品bean
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                // 由于经过init之后的操作,earlySingletonReference和exposedObject可能不是一个实例,
                // 这里需要让他们指向一个实例,
                exposedObject = earlySingletonReference;
            // 不允许在循环依赖情况下注入原始bean && 当前bean被其他bean依赖
            }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                // 拿到当前bean依赖所有bean的数组
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    // 移除这些bean,因为这些bean依赖的bean是被增强过的bean
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        // 移除失败的添加到actualDependentBeans
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    throw new BeanCurrentlyInCreationException(beanName,
                            "Bean with name '" + beanName + "' has been injected into other beans [" +
                            StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                            "] in its raw version as part of a circular reference, but has eventually been " +
                            "wrapped. This means that said other beans do not use the final version of the " +
                            "bean. This is often the result of over-eager type matching - consider using " +
                            "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    try {
        // 注册用于销毁的bean,
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

代码块1中2处

                                        代码块2

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;

    // bean不是null && mbd不是合成 && 有InstantiationAwareBeanPostProcessor
    if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

        // 遍历执行BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 具体的处理逻辑位于AutowiredAnnotationBeanPostProcessor中,它继承了这个方法,最终返回的还是是bean本身,
                // 注意:如果有别的实现了SmartInstantiationAwareBeanPostProcessor就未必了
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                if (exposedObject == null) {
                    return exposedObject;
                }
            }
        }
    }
    return exposedObject;
}

此时我相信这里你肯定是可以看明白的

代码块1中3处

这个populateBean方法,即是处理属性注入的地方,@Autowired,@Resource,@Value,甚至是当你使用Dubbo框架的时候@Reference都是在这里处理注入的,我们一起看看这个方法:

                                        代码块3

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    PropertyValues pvs = mbd.getPropertyValues();
    // 进行基本的校验,bw为null时
    if (bw == null) {
        // 如果有属性值,则抛异常
        if (!pvs.isEmpty()) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        // 否则 结束方法
        }else {
            return;
        }
    }

    // 是否继续填充属性的标记
    boolean continueWithPropertyPopulation = true;
    // mbd是否为合成 && 是否存在InstantiationAwareBeanPostProcessor
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // postProcessAfterInstantiation这个方法是在bean实例化后属性填充之前调用
                // 返回的是true,说明应该进行属性填充,false说明不应该
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }
    // 如果不该继续填充了则直接返回
    if (!continueWithPropertyPopulation) {
        return;
    }
    // 这个是处理xml中autowire的值为byname 和 byType的逻辑
    // 可以看出来只有xml的才会走这里,注解的没有byName 和 byType这样的属性
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

        // 1.byName的处理
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }

        // 2.byType的处理
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    // 是否有InstantiationAwareBeanPostProcessors
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // 是否需要依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (hasInstAwareBpps || needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    // 用InstantiationAwareBeanPostProcessor的后置处理来进行属性的填充
                    // 这里进行的是属性填充前最后一步的处理,@AutoWired就是在这里进行处理的
                    // 也就是说这里会对@Autowired的属性进行初始化,然后加到pvs中来
                    // 当然,@Resource也是在这里处理的,只是用的BeanPostProcessor不是一个
                    // 注:@Autowired的处理逻辑在AutowiredAnnotationBeanPostProcessor中,而
                    // @Resource的在CommonAnnotationBeanPostProcessor里
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            // 对filteredPds里面的属性进行依赖检查
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }
    // 3.进行填充操作
    applyPropertyValues(beanName, mbd, bw, pvs);
}

这个代码块中的1、2个,是针对xml中bean标签的autowire属性的,虽然现在用的很少了,但是本着完整的原则,还是来看看它:

代码块3中1处

                                        代码块4

protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
    // 获取需要注入的属性的名称
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        // 如果现在beanFactory容器中有这个propertyName对应的bean或者是
        // 对应的beanDefinition
        if (containsBean(propertyName)) {
            // 则去初始化这个bean
            Object bean = getBean(propertyName);
            // 将所依赖的bean加入pvs容器中以备后续使用
            pvs.add(propertyName, bean);
            // 注册依赖关系
            registerDependentBean(propertyName, beanName);
            if (logger.isDebugEnabled()) {
                logger.debug("Added autowiring by name from bean name '" + beanName +
                        "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                        "' by name: no matching bean found");
            }
        }
    }
}

代码块3中2处

                                        代码块5

protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

    // 拿自定义的TypeConverter,如果为空,则用bw做TypeConverter
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }

    Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
    // 拿到需要注入的属性的名称
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        try {
            // 拿到bw的对应这个propertyName的PropertyDescriptor
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            // 如果pd是个Object类型的,则不注入这个。原因是如果是Object,你找到的参数即使类型不匹配
            // 也能注入成功。。
            if (!Object.class.equals(pd.getPropertyType())) {
                MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                // Do not allow eager init for type matching in case of a prioritized post-processor.
                boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
                DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                // 真正的解析过程
                Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                // 把解析成功的参数放到pvs里
                if (autowiredArgument != null) {
                    pvs.add(propertyName, autowiredArgument);
                }
                for (String autowiredBeanName : autowiredBeanNames) {
                    registerDependentBean(autowiredBeanName, beanName);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
                                propertyName + "' to bean named '" + autowiredBeanName + "'");
                    }
                }
                autowiredBeanNames.clear();
            }
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
        }
    }
}

代码块3中3处

到了3、3这里,spring已经知道了bean的哪个属性需要注入,并且注入的值已经拿到,我们来看看这里的代码:

                                        代码块6

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    // 如果pvs为空过直接返回
    if (pvs == null || pvs.isEmpty()) {
        return;
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (System.getSecurityManager() != null) {
        if (bw instanceof BeanWrapperImpl) {
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }
    }

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        // 如果mpvs的属性值已经被转换成为对应的类型,则可以直接去设置
        if (mpvs.isConverted()) {
            try {
                // 这里也是为什么使用BeanWrapper而不是使用beanInstance的原因
                // 因为BeanWrapper实现了PropertyAccessor接口,可以直接给set值
                // 这块有兴趣的可以自行研究一下
                bw.setPropertyValues(mpvs);
                return;
            }catch (BeansException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        original = mpvs.getPropertyValueList();
    }else {
        // 获取原始的属性
        original = Arrays.asList(pvs.getPropertyValues());
    }

    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    // 获取解析器
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // 对原始属性进行深拷贝,避免修改后引起的原始属性值修改
    // deepcopy是后边直接用作给bean填充属性的
    List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    boolean resolveNecessary = false;
    for (PropertyValue pv : original) {
        // 如果某个属性被转换过则直接加入deepCopy
        if (pv.isConverted()) {
            deepCopy.add(pv);
        // 否则的话进行转换
        }else {
            // 拿到原始属性值和属性名称
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            // 并进行解析,并进行必要的解析
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            // propertyName对应的属性是个可以写的 && 不能是嵌套属性或者下标属性
            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));
            }
        }
    }
    // 将converted设置为true
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }

    // 用deepCopy里的值来进行属性填充
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

这下doCreateBean中对bean的填充也完了,其实对bean的工作都是在BeanPostProcessor中完成的,在populateBean这个方法中只是对BeanPostProcessor的方法进行了调用而已。我们继续看1.4处,这个方法主要是针对bean的初始化的。

代码块1中4处

                                        代码块7

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        // 调用几个Aware接口
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    // 1.调用aware
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

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

        try {
            // 3.调用InitializingBean的方法和自定义初始化方法
            invokeInitMethods(beanName, wrappedBean, mbd);
        }catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }

        // 4.执行所有BeanPostProcessor的postProcessAfterInitialization方法
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }

第1处主要是调用aware接口,aware接口我也会去写文章专门介绍,我们这会先来看这个方法做了什么:

代码块7中1处

                                        代码块8

private void invokeAwareMethods(final String beanName, final Object bean) {
    // 所谓的xxxAware,就是让这个bean和xxx产生关联
    if (bean instanceof Aware) {
        // 设置名称
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        // 类加载器
        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        // 我们有时候使用BeanFactoryAware去拿BeanFactory,就是在这步设置的
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

代码块7中2处

                                        代码块9

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

    Object result = existingBean;
    // 调用所有的BeanPostProcessor的postProcessBeforeInitialization(前置处理)方法
    // 其中@PostConstruct就是在CommonAnnotationBeanPostProcessor中执行的
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

代码块7中3处

这个方法主要是执行初始化方法,主要执行@InitialBean中的初始化方法和自定义的初始化方法:

                                        代码块10

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
    // 调用InitializingBean的afterPropertiesSet方法,还是特权调用和普通调用
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isDebugEnabled()) {
            logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                    @Override
                    public Object run() throws Exception {
                        // 
                        ((InitializingBean) bean).afterPropertiesSet();
                        return null;
                    }
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }


    if (mbd != null) {
        String initMethodName = mbd.getInitMethodName();
        if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 调用自定义的初始化方法,主要是通过反射调用
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

代码块7中4处

这个方法也是初始化的最后一步

                                        代码块11

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
    // 执行所有BeanPostProcessor的postProcessAfterInitialization(后置处理)方法
    Object result = existingBean;
    // 遍历执行
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

至此,xml中bean的加载解析我们已经讲完,下一篇,我们将对整个流程做个总结,以及扩充一些面试涉及到的点,以让你更好的理解bean加载的整个流程。

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » 深入理解Spring IOC(六)、 bean的填充以及初始化工作

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏