Ioc容器中依赖注入-解析

这是通过BeanDefintionResolver来对BeanDefintion进行解析,然后在注入到property中
下面是对BeanDefintionValueResolver中去看解析的过程这里是对BeanReference的解析的源码分析
下面是对解析ResolveRef方法的解析:

//这里是解析BeanReference对象的方法 
@Nullable
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
            //获取Bean的名字
            String refName = ref.getBeanName();
            refName = String.valueOf(this.doEvaluate(refName));
            Object bean;
            //判断ref是否位于双亲ioc容器中,如果存在就从容器中去获取
            if (ref.isToParent()) {
                if (this.beanFactory.getParentBeanFactory() == null) {
                    throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Can't resolve reference to bean '" + refName + "' in parent factory: no parent factory available");
                }
                //直接调用getBean方法来获取对象
                bean = this.beanFactory.getParentBeanFactory().getBean(refName);
            } else {
                //如果不是双亲ioc容器那么就从当前容器中去获取
                bean = this.beanFactory.getBean(refName);
                //并且将refName,beanName注册到工厂中去
                this.beanFactory.registerDependentBean(refName, this.beanName);
            }

            if (bean instanceof NullBean) {
                bean = null;
            }
            
            //直接返回获取到的bean对象
            return bean;
        } catch (BeansException var5) {
            throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, var5);
        }
    }

下面主要是对其它属性进行注入的例子
resolveManagedArray 是对manangeArray集合进行解析的方法

 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, this.resolveValueIfNecessary(new BeanDefinitionValueResolver.KeyedArgName(argName, i), ml.get(i)));
        }

        return resolved;
    }


//下面是对于resolveManageList集合进行解析的源码分析
private List<?> resolveManagedList(Object argName, List<?> ml) {
     //定义一个数组,并且设置好数组的长度,作为一个封装数组添加解析的元素属性结果
        List<Object> resolved = new ArrayList(ml.size());
    
        //循环遍历List集合中的元素
        for(int i = 0; i < ml.size(); ++i) {
            resolved.add(this.resolveValueIfNecessary(new BeanDefinitionValueResolver.KeyedArgName(argName, i), ml.get(i)));
        }

        return resolved;
    }

在前面这两个属性的注入都调用了resolveValueIfNecessary,这个方法就是包括了所有的属性的注入方法
下面主要就是看下这个方法中的代码实现逻辑:
resolveValueIfNecessary:

//这个解析方法主要的就是对各种不同的类型来做解析方法的分析
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
    //RuntimeBeanReference对象的生成就是在对解析BeanDefintion时生成的
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference)value;
            //这是从ioc容器中或者是双亲ioc容器中去获取bean实例
            return this.resolveReference(argName, ref);
        } else if (value instanceof RuntimeBeanNameReference) {
            //这是对RuntimeBeanNameReference对象来进行解析的,同时也是直接就返回refname属性即可
            String refName = ((RuntimeBeanNameReference)value).getBeanName();
            refName = String.valueOf(this.doEvaluate(refName));
            //在ioc容器中判断是否包括refName属性
            if (!this.beanFactory.containsBean(refName)) {
                throw new BeanDefinitionStoreException("Invalid bean name '" + refName + "' in bean reference for " + argName);
            } else {
                return refName;
            }
            //解析BeanDefintionHolder对象
        } else if (value instanceof BeanDefinitionHolder) {
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder)value;
            return this.resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
            //解析BeanDefintion对象
        } else if (value instanceof BeanDefinition) {
            BeanDefinition bd = (BeanDefinition)value;
            String innerBeanName = "(inner bean)#" + ObjectUtils.getIdentityHexString(bd);
            return this.resolveInnerBean(argName, innerBeanName, bd);
        } else if (value instanceof ManagedArray) {
            ManagedArray array = (ManagedArray)value;
            Class<?> elementType = array.resolvedElementType;
            if (elementType == null) {
                String elementTypeName = array.getElementTypeName();
                if (StringUtils.hasText(elementTypeName)) {
                    try {
                        elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                        array.resolvedElementType = elementType;
                    } catch (Throwable var7) {
                        throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, var7);
                    }
                } else {
                    elementType = Object.class;
                }
            }

            return this.resolveManagedArray(argName, (List)value, elementType);
        } else if (value instanceof ManagedList) {
            return this.resolveManagedList(argName, (List)value);
        } else if (value instanceof ManagedSet) {
            return this.resolveManagedSet(argName, (Set)value);
        } else if (value instanceof ManagedMap) {
            return this.resolveManagedMap(argName, (Map)value);
        } else if (value instanceof ManagedProperties) {
            Properties original = (Properties)value;
            Properties copy = new Properties();
            original.forEach((propKey, propValue) -> {
                if (propKey instanceof TypedStringValue) {
                    propKey = this.evaluate((TypedStringValue)propKey);
                }

                if (propValue instanceof TypedStringValue) {
                    propValue = this.evaluate((TypedStringValue)propValue);
                }

                if (propKey != null && propValue != null) {
                    copy.put(propKey, propValue);
                } else {
                    throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting Properties key/value pair for " + argName + ": resolved to null");
                }
            });
            return copy;
        } else if (value instanceof TypedStringValue) {
            TypedStringValue typedStringValue = (TypedStringValue)value;
            Object valueObject = this.evaluate(typedStringValue);

            try {
                Class<?> resolvedTargetType = this.resolveTargetType(typedStringValue);
                return resolvedTargetType != null ? this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType) : valueObject;
            } catch (Throwable var8) {
                throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, var8);
            }
        } else {
            return value instanceof NullBean ? null : this.evaluate(value);
        }
    }
  
    
    //这些源代码就是有很多的地方没有看懂代码实现逻辑思维
    这个解析方法完成之后就是相当于是已经为依赖注入准备好了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中属性是各种各样的
发布了51 篇原创文章 · 获赞 0 · 访问量 740

猜你喜欢

转载自blog.csdn.net/a_liuren/article/details/103877586