【Spring源码阅读】populateBean实现 依赖注入源码解析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。

测试代码

下面开始进入源码分析之前,先基于以下实例进行:

    // 基础属性类
    public class Student {

        private String name;

        public Student(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Student [name=" + name + "]";
        }
    }

    // 需要进行依赖注入的类
    public class TestBean {

        private Student student;

        public void echo() {
            System.out.println("I'm a student : " + student);
        }

        public Student getStudent() {
            return student;
        }

        public void setStudent(Student student) {
            this.student = student;
        }
    }

配置代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

        <bean class="com.jeanheo.model.Student" id="student">
            <constructor-arg index="0" value="test"/>
        </bean>
        <bean class="com.jeanheo.model.TestBean2" id="testBean">
            <property name="student" ref="student"/>
        </bean>

    </beans>

具体测试代码:

    public class BaseTest {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
            TestBean testBean = context.getBean("testBean", TestBean.class);
            testBean.echo();
        }
    }

源码分析

下面基于TestBean的依赖注入进行分析相关源码:

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        // pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
        // 在本例中,里面存在一个propertyValueList,里面只有一个propertyValue:key->value="student"->RuntimeBeanReference("<student>")
        PropertyValues pvs = mbd.getPropertyValues();

        if (bw == null) {
            if (!pvs.isEmpty()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // 空对象直接返回
                return;
            }
        }

        // 给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
        // 具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
        boolean continueWithPropertyPopulation = true;

        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }

        // 根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml文件中有显式的配置
        // 如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            // 深拷贝当前已有的配置
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // 根据名称进行注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // // 根据类型进行注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            // 结合注入后的配置,覆盖当前配置
            pvs = newPvs;
        }

        // 容器是否注册了InstantiationAwareBeanPostProcessor
        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 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);
            }
        }
        // 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中,注意到这一步,TestBean的student属性还是RuntimeBeanReference,即还未解析实际的Student实例
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

在具体分析源码如何将将pvs上所有的属性填充到BeanWrapper对应的Bean实例中之前,先看看autowireByName和autowireByType这两步是怎么实现的:

    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        // 根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
        // 简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            if (containsBean(propertyName)) {
                // 递归初始化相关Bean
                Object bean = getBean(propertyName);
                // 根据名称添加到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");
                }
            }
        }
    }

    // 简单类型判定
    public static boolean isSimpleValueType(Class<?> clazz) {
        return ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.isEnum() ||
                CharSequence.class.isAssignableFrom(clazz) ||
                Number.class.isAssignableFrom(clazz) ||
                Date.class.isAssignableFrom(clazz) ||
                clazz.equals(URI.class) || clazz.equals(URL.class) ||
                clazz.equals(Locale.class) || clazz.equals(Class.class);
    }

类似的,下面再看看autowireByType的实现

    protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        // 获取类型转换器
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }

        Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
        // 类似的,过滤出满足装配条件的Bean属性
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            try {
                如果是Object类型不进行装配
                if (!Object.class.equals(pd.getPropertyType())) {
                    // 获取相关的写方法参数
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // 定义是否允许懒加载。
                    boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
                    // 
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    // 这里会根据传入desc里的入参类型,作为依赖装配的类型
                    // 再根据这个类型在BeanFacoty中查找所有类或其父类相同的BeanName
                    // 最后根据BeanName获取或初始化相应的类,然后将所有满足条件的BeanName填充到autowiredBeanNames中。
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    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);
            }
        }
    }

具体pvs上所有的属性填充到BeanWrapper对应的Bean实例中实现如下:

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues 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;
            if (mpvs.isConverted()) {
                // 如果已被设置转换完成,直接完成配置
                try {
                    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解析器,用来解析未被解析的PropertyValue。
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // 开始遍历检查original中的属性,对未被解析的先解析/已解析的直接加入deepCopy中,最后再填充到具体的Bean实例中
        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();
                // 核心逻辑,解析获取实际的值
                // 对于RuntimeReference,会解析拿到具体的beanName,最终通过getBean(beanName)拿到具体的对象
                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));
                }
            }
        }
        if (mpvs != null && !resolveNecessary) {
            mpvs.setConverted();
        }

        // 完成设置
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

上面大致的描述了Spring完成依赖注入的流程,中间具体还有很多细致的复杂处理细节,但通过上述的源码解读,我们大致了解了整个Spring容器的依赖注入实现基础流程。


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » 【Spring源码阅读】populateBean实现 依赖注入源码解析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

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

支付宝扫一扫打赏

微信扫一扫打赏