Spring源码学习【五】填坑篇之PropertyValue解析

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

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

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

经过上一篇文章 Spring源码学习【四】依赖注入过程 对Spring依赖注入过程的分析,我们知道了在注入Property时会创建一个深拷贝副本,将这个副本持有的Property注入到Bean中,在创建的过程中会使用BeanDefinitionValueResolver解析PropertyValue,代码如下:

    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

这里调用了BeanDefinitionValueResolver的resolveValueIfNecessary方法,在这个方法中,将BeanDefinition中定义的Property解析为真正的对象,代码如下:

    class BeanDefinitionValueResolver {

        ...

        @Nullable
        public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
            // 解析Bean引用
            if (value instanceof RuntimeBeanReference) {
                RuntimeBeanReference ref = (RuntimeBeanReference) value;
                return resolveReference(argName, ref);
            }
            // 解析Bean name引用
            else if (value instanceof RuntimeBeanNameReference) {
                String refName = ((RuntimeBeanNameReference) value).getBeanName();
                refName = String.valueOf(doEvaluate(refName));
                if (!this.beanFactory.containsBean(refName)) {
                    throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);
                }
                return refName;
            }
            // 解析BeanDefinition,包含Bean name、aliases等
            else if (value instanceof BeanDefinitionHolder) {
                BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
                return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
            }
            // 解析原始BeanDefinition
            else if (value instanceof BeanDefinition) {
                BeanDefinition bd = (BeanDefinition) value;
                String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(bd);
                return resolveInnerBean(argName, innerBeanName, bd);
            }
            // 解析Array
            else if (value instanceof ManagedArray) {
                ManagedArray array = (ManagedArray) value;
                Class<?> elementType = array.resolvedElementType;
                // 如果未指定列表元素类型,则通过元素类型名获取元素类型或认为是Object类型
                if (elementType == null) {
                    String elementTypeName = array.getElementTypeName();
                    if (StringUtils.hasText(elementTypeName)) {
                        try {
                            elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                            array.resolvedElementType = elementType;
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, ex);
                        }
                    }
                    else {
                        elementType = Object.class;
                    }
                }
                return resolveManagedArray(argName, (List<?>) value, elementType);
            }
            // 解析List
            else if (value instanceof ManagedList) {
                return resolveManagedList(argName, (List<?>) value);
            }
            // 解析Set
            else if (value instanceof ManagedSet) {
                // May need to resolve contained runtime references.
                return resolveManagedSet(argName, (Set<?>) value);
            }
            // 解析Map
            else if (value instanceof ManagedMap) {
                // May need to resolve contained runtime references.
                return resolveManagedMap(argName, (Map<?, ?>) value);
            }
            // 解析Properties
            else if (value instanceof ManagedProperties) {
                Properties original = (Properties) value;
                Properties copy = new Properties();
                original.forEach((propKey, propValue) -> {
                    if (propKey instanceof TypedStringValue) {
                        propKey = evaluate((TypedStringValue) propKey);
                    }
                    if (propValue instanceof TypedStringValue) {
                        propValue = evaluate((TypedStringValue) propValue);
                    }
                    if (propKey == null || propValue == null) {
                        throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting Properties key/value pair for " + argName + ": resolved to null");
                    }
                    copy.put(propKey, propValue);
                });
                return copy;
            }
            // 解析带有目标类型的字符串
            else if (value instanceof TypedStringValue) {
                TypedStringValue typedStringValue = (TypedStringValue) value;
                Object valueObject = evaluate(typedStringValue);
                try {
                    Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
                    if (resolvedTargetType != null) {
                        return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                    }
                    else {
                        return valueObject;
                    }
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, ex);
                }
            }
            else if (value instanceof NullBean) {
                return null;
            }
            else {
                return evaluate(value);
            }
        }
    }

从上面的代码中可以看到,最终会返回一个解析好的真实对象,我们仍然以集合类型Property看一下具体的解析方法,代码如下:

    class BeanDefinitionValueResolver {

        ...

        /**
         * 解析ManagedArray,可能存在Bean引用的情况
         */
        private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
            Object resolved = Array.newInstance(elementType, ml.size());
            for (int i = 0; i < ml.size(); i++) {
                Array.set(resolved, i,resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
            }
            return resolved;
        }

        /**
         * 解析ManagedList
         */
        private List<?> resolveManagedList(Object argName, List<?> ml) {
            List<Object> resolved = new ArrayList<>(ml.size());
            for (int i = 0; i < ml.size(); i++) {
                resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
            }
            return resolved;
        }

        /**
         * 解析ManagedSet
         */
        private Set<?> resolveManagedSet(Object argName, Set<?> ms) {
            Set<Object> resolved = new LinkedHashSet<>(ms.size());
            int i = 0;
            for (Object m : ms) {
                resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
                i++;
            }
            return resolved;
        }

        /**
         * 解析ManagedMap
         */
        private Map<?, ?> resolveManagedMap(Object argName, Map<?, ?> mm) {
            Map<Object, Object> resolved = new LinkedHashMap<>(mm.size());
            mm.forEach((key, value) -> {
                Object resolvedKey = resolveValueIfNecessary(argName, key);
                Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value);
                resolved.put(resolvedKey, resolvedValue);
            });
            return resolved;
        }

    }

从上面的代码中我们看到,最终创建了相应的集合数据结构,并将集合元素添加到了集合中,这样BeanDefinition中定义的Property就解析为一个真正的对象了,下面就可以进行依赖的注入了。


来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring源码学习【五】填坑篇之PropertyValue解析

评论 抢沙发

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

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

支付宝扫一扫打赏

微信扫一扫打赏