Spring源码分析----IOC依赖注入

来源:互联网 发布:新浪微博粉丝数据分析 编辑:程序博客网 时间:2024/05/16 19:33

本文参考《spring技术内幕第2版》,spring4

    前面对IoC容器的初始化过程进行了详细的分析,这个初始化过程的主要工作是在IoC容器中建立BeanDefinition数据映射。在此过程中并没有看到IoC容器对Bean依赖关系 进行注入,接入来进行分析
    假设当前IoC容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理。首先,注意到依赖注入的过程是用户第一次向IoC容器索要Bean时触发的,【当然也有例外,也就是我们可以在BeanDefinition信息中通过控制lazy-init属性来让容器完成对Bean的预实例化,这个预实例化实际上也是一个完成依赖注入的过程,但它是在初始化的过程中完成的,稍后分析这一过程】。当用户向IoC容器索要Bean时,在基本的IoC容器接口BeanFactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入发生的地方。


    为了进一步了解这个依赖注入过程的实现,下面从DefaultListableBeanFactory的基类AbstractBeanFactory入手去看getBean的实现。

public interface BeanFactory {    String FACTORY_BEAN_PREFIX = "&";    Object getBean(String var1) throws BeansException;    <T> T getBean(String var1, Class<T> var2) throws BeansException;    <T> T getBean(Class<T> var1) throws BeansException;    Object getBean(String var1, Object... var2) throws BeansException;    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;    boolean containsBean(String var1);    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;    String[] getAliases(String var1);}

----------------------------------// BeanFactory实现子类 public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory     /*这里是对BeanFactory接口的实现,比如getBean接口方法      这些getBean接口方法最终是通过调用doGetBean来实现的*/    public Object getBean(String name) throws BeansException {        return this.doGetBean(name, (Class)null, (Object[])null, false);    }    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {        return this.doGetBean(name, requiredType, (Object[])null, false);    }    public Object getBean(String name, Object... args) throws BeansException {        return this.doGetBean(name, (Class)null, args, false);    }    public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {        return this.doGetBean(name, requiredType, args, false);    }    // 这里是实际取得bean的地方,也是触发依赖注入的入口    protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {        final String beanName = this.transformedBeanName(name);        // 先从缓存中取得Bean,处理那些已经被创建过的单件模式的Bean,对这种Bean的请求不需要重复地创建        Object sharedInstance = this.getSingleton(beanName);        Object bean;        if(sharedInstance != null && args == null) {            if(this.logger.isDebugEnabled()) {                if(this.isSingletonCurrentlyInCreation(beanName)) {                    this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");                } else {                    this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");                }            }    /* [FactoryBean的实现]---->这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得FactoryBean的生产结果      BeanFactory和FactoryBean的区别已经在前面讲过,后面详细分析*/            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);        } else {            if(this.isPrototypeCurrentlyInCreation(beanName)) {                throw new BeanCurrentlyInCreationException(beanName);            }    /* 这里对IoC容器中的BeanFactory是否存在进行检查,检查是否能在当前的BeanFactory中取得需要的Bean.     如果在当前的工厂中取不到,则到双亲BeanFactory中去取;    如果当前的双亲工厂取不到,那就顺着双亲BeanFactory链一直向上找*/            BeanFactory ex = this.getParentBeanFactory();            if(ex != null && !this.containsBeanDefinition(beanName)) {                String var24 = this.originalBeanName(name);                if(args != null) {                    return ex.getBean(var24, args);                }                return ex.getBean(var24, requiredType);            }            if(!typeCheckOnly) {                this.markBeanAsCreated(beanName);            }            try {// 这里根据Bean的名字取得BeanDefinition                final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);                this.checkMergedBeanDefinition(ex1, beanName, args);  // 获取当前的Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取得一个没有任何依赖的Bean为止                String[] dependsOn = ex1.getDependsOn();                String[] scopeName;                if(dependsOn != null) {                    scopeName = dependsOn;                    int scope = dependsOn.length;                    for(int ex2 = 0; ex2 < scope; ++ex2) {                        String dependsOnBean = scopeName[ex2];                        if(this.isDependent(beanName, dependsOnBean)) {                            throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dependsOnBean + "\'");                        }                        this.registerDependentBean(dependsOnBean, beanName);                        this.getBean(dependsOnBean);                    }                }/* 这里通过调用createBean方法创建Singleton bean的实例,这有一个回调函数getObject,会在getSingleton中调用ObjectFactory的createBean*/                if(ex1.isSingleton()) {                    sharedInstance = this.getSingleton(beanName, new ObjectFactory() {                        public Object getObject() throws BeansException {                            try {                                return AbstractBeanFactory.this.createBean(beanName, ex1, args); // ------->                            } catch (BeansException var2) {                                AbstractBeanFactory.this.destroySingleton(beanName);                                throw var2;                            }                        }                    });                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);                } else if(ex1.isPrototype()) { // 这里是创建prototype bean的地方                    scopeName = null;                    Object var25;                    try {                        this.beforePrototypeCreation(beanName);                        var25 = this.createBean(beanName, ex1, args);//----->                    } finally {                        this.afterPrototypeCreation(beanName);                    }                    bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);                } else {                    String var26 = ex1.getScope();                    Scope var27 = (Scope)this.scopes.get(var26);                    if(var27 == null) {                        throw new IllegalStateException("No Scope registered for scope \'" + var26 + "\'");                    }                    try {                        Object var28 = var27.get(beanName, new ObjectFactory() {                            public Object getObject() throws BeansException {                                AbstractBeanFactory.this.beforePrototypeCreation(beanName);                                Object var1;                                try {                                    var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);                                } finally {                                    AbstractBeanFactory.this.afterPrototypeCreation(beanName);                                }                                return var1;                            }                        });                        bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);                    } catch (IllegalStateException var21) {                        throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' is not active for the current thread; " + "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var21);                    }                }            } catch (BeansException var23) {                this.cleanupAfterBeanCreationFailure(beanName);                throw var23;            }        }/* 这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean,  这个Bean已经是包含了依赖关系的bean */        if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {            try {                return this.getTypeConverter().convertIfNecessary(bean, requiredType);            } catch (TypeMismatchException var22) {                if(this.logger.isDebugEnabled()) {                    this.logger.debug("Failed to convert bean \'" + name + "\' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22);                }                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());            }        } else {            return bean;        }    }    protected abstract Object createBean(String var1, RootBeanDefinition var2, Object[] var3) throws BeanCreationException;
    上面就是依赖注入的入口,在这里触发了依赖注入,而依赖注入的发生是在容器中的BeanDefinition数据已经建立好的前提下进行的。
    下面详解分析依赖注入的过程。重点来说,getBean是依赖注入的起点,之后会调用createBean.。
// public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory     /** 在这个方法中,Bean对象会依据BeanDefinition定义的要求生成     该方法不但生成了需要的Bean,还以Bean初始化进行了处理,如实现了BeanDefinition中的init-method属性定义,Bean后置处理器等*/    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {        if(this.logger.isDebugEnabled()) {            this.logger.debug("Creating instance of bean \'" + beanName + "\'");        }// 这里判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入        this.resolveBeanClass(mbd, beanName, new Class[0]);        try {            mbd.prepareMethodOverrides();        } catch (BeanDefinitionValidationException var5) {            throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);        }        Object beanInstance;        try {    // 如果Bean配置了PostProcessor,那么这里返回的是一个proxy            beanInstance = this.resolveBeforeInstantiation(beanName, mbd);            if(beanInstance != null) {                return beanInstance;            }        } catch (Throwable var6) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);        }// 这里是创建Bean的调用        beanInstance = this.doCreateBean(beanName, mbd, args);  //---------------------->        if(this.logger.isDebugEnabled()) {            this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");        }        return beanInstance;    }    // 这里是Bean怎样生成的    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {// 这个BeanWrapper是用来持有创建出来的Bean对象的        BeanWrapper instanceWrapper = null;// 如果是Singleton,先把缓存中的同名Bean清除        if(mbd.isSingleton()) {            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);        }// 这里是创建Bean的地方,由createBeanInstance来完成的        if(instanceWrapper == null) {            instanceWrapper = this.createBeanInstance(beanName, mbd, args);  // -------------------->        }        final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;        Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;        Object earlySingletonExposure = mbd.postProcessingLock;        synchronized(mbd.postProcessingLock) {            if(!mbd.postProcessed) {                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                mbd.postProcessed = true;            }        }        boolean var19 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);        if(var19) {            if(this.logger.isDebugEnabled()) {                this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");            }            this.addSingletonFactory(beanName, new ObjectFactory() {                public Object getObject() throws BeansException {                    return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);                }            });        }// 这里是对Bean的初始化,依赖注入往往在这里发生,// 这个exposeObject在初始化处理完以后会返回作为依赖注入完成后的Bean        Object exposedObject = bean;        try {            this.populateBean(beanName, mbd, instanceWrapper); // ----------------->            if(exposedObject != null) {                exposedObject = this.initializeBean(beanName, exposedObject, mbd); // ------------------>            }        } catch (Throwable var17) {            if(var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {                throw (BeanCreationException)var17;            }            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);        }        if(var19) {            Object ex = this.getSingleton(beanName, false);            if(ex != null) {                if(exposedObject == bean) {                    exposedObject = ex;                } else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {                    String[] dependentBeans = this.getDependentBeans(beanName);                    LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);                    String[] var12 = dependentBeans;                    int var13 = dependentBeans.length;                    for(int var14 = 0; var14 < var13; ++var14) {                        String dependentBean = var12[var14];                        if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                            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 {            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);            return exposedObject;        } catch (BeanDefinitionValidationException var16) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);        }    }
    在这里看到,与依赖注入关系特别密切的方法createBeanInstance和populateBean,下面分别介绍这两个方法。
    /** 在这个方法中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式,     可以通过工厂方法或者容器的autowire特性生成,这些生成方式都是由相关的BeanDefinition来指定的*/    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {// 确认需要创建的Bean实例的类可以实例化        Class beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);        if(beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn\'t public, and non-public access not allowed: " + beanClass.getName());        } else if(mbd.getFactoryMethodName() != null) {    // 这里使用工厂方法对Bean进行实例化            return this.instantiateUsingFactoryMethod(beanName, mbd, args);        } else {            boolean resolved = false;            boolean autowireNecessary = false;            if(args == null) {                Object ctors = mbd.constructorArgumentLock;                synchronized(mbd.constructorArgumentLock) {                    if(mbd.resolvedConstructorOrFactoryMethod != null) {                        resolved = true;                        autowireNecessary = mbd.constructorArgumentsResolved;                    }                }            }            if(resolved) {                return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd);            } else {// 使用构造函数进行实例化                Constructor[] ctors1 = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);                return ctors1 == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors1, args);            }        }    }    // 最常见的实例化过程,使用构造函数进行实例化    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {        try {            Object ex;            if(System.getSecurityManager() != null) {                ex = AccessController.doPrivileged(new PrivilegedAction() {                    public Object run() {                        return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this);                    }                }, this.getAccessControlContext());            } else {/* 使用默认的实例化策略对Bean进行实例化,默认的实例化策略是CglibSubclassingInstantiationStrategy, 也就是CGLIB来对Bean进行实例化*/                ex = this.getInstantiationStrategy().instantiate(mbd, beanName, this);  // ----------------->            }            BeanWrapperImpl bw = new BeanWrapperImpl(ex);            this.initBeanWrapper(bw);            return bw;        } catch (Throwable var6) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);        }    }
    这里用CGLIB对Bean进行实例化。CGLIB是一个常用的字节码生成器的类库,它提供一系列API来提供生成和转换Java的字节码的功能。在Spring AOP中也使用CGLIB对Java的字节码进行增强。在IoC容器中,要了解怎样使用CGLIB来生成Bean对象,需要看一下SimpleInstantiationStrategy类。这个Strategy是Spring用来生成Bean对象的默认类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,它使用JVM的反射功能,一种是通过前面提到的CGLIB来生成,如下:
public interface InstantiationStrategy {    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3) throws BeansException; // ------------->    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Constructor<?> var4, Object[] var5) throws BeansException;    Object instantiate(RootBeanDefinition var1, String var2, BeanFactory var3, Object var4, Method var5, Object[] var6) throws BeansException;}public class SimpleInstantiationStrategy implements InstantiationStrategy {......    // 该类这个方法生成 java对象    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {        if(beanDefinition.getMethodOverrides().isEmpty()) {            Object var5 = beanDefinition.constructorArgumentLock;    // 这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化            Constructor constructorToUse;            synchronized(beanDefinition.constructorArgumentLock) {                constructorToUse = (Constructor)beanDefinition.resolvedConstructorOrFactoryMethod;                if(constructorToUse == null) {                    final Class clazz = beanDefinition.getBeanClass();                    if(clazz.isInterface()) {                        throw new BeanInstantiationException(clazz, "Specified class is an interface");                    }                    try {                        if(System.getSecurityManager() != null) {                            constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction() {                                public Constructor<?> run() throws Exception {                                    return clazz.getDeclaredConstructor((Class[])null);                                }                            });                        } else {                            constructorToUse = clazz.getDeclaredConstructor((Class[])null);                        }                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;                    } catch (Exception var9) {                        throw new BeanInstantiationException(clazz, "No default constructor found", var9);                    }                }            }    /* 通过BeanUtils进行实例化,这个BeanUtils的实例化通过Constructor来实例化Bean,     在BeanUtils中可以看到具体的调用ctor.newInstance(args))*/            return BeanUtils.instantiateClass(constructorToUse, new Object[0]);        } else {    // 使用CGLIB来实例化对象            return this.instantiateWithMethodInjection(beanDefinition, beanName, owner);        }    }......}
    到这里已经分析了实例化Bean对象的整个过程。
    在实例化Bean对象生成的基础上,再介绍一下Spring是怎样对这些对象进行处理的,也就是Bean对象生成以后,怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入过程。这个过程涉及对各种Bean对象的属性的处理过程(即依赖关系处理的过程),这个依赖关系处理的依据就是已经解析得到的BeanDefinition。要详细了解这个过程,需要回到前面的pupulateBean方法,代码如下:
// public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory     protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {    /* 这里取得在BeanDefinition中设置的property值,这些property来自对BeanDefinition的解析,具体的解析过程可以参看载入和解析BeanDefinition的分析*/        Object pvs = mbd.getPropertyValues();        if(bw == null) {            if(!((PropertyValues)pvs).isEmpty()) {                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");            }        } else {            boolean continueWithPropertyPopulation = true;            if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {                Iterator hasInstAwareBpps = this.getBeanPostProcessors().iterator();                while(hasInstAwareBpps.hasNext()) {                    BeanPostProcessor needsDepCheck = (BeanPostProcessor)hasInstAwareBpps.next();                    if(needsDepCheck instanceof InstantiationAwareBeanPostProcessor) {                        InstantiationAwareBeanPostProcessor filteredPds = (InstantiationAwareBeanPostProcessor)needsDepCheck;                        if(!filteredPds.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {                            continueWithPropertyPopulation = false;                            break;                        }                    }                }            }            if(continueWithPropertyPopulation) {// 开始进行依赖注入过程,先处理autowire的注入                if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {                    MutablePropertyValues hasInstAwareBpps1 = new MutablePropertyValues((PropertyValues)pvs);        // 这里是对autowire注入的处理,可以根据Bean的名字或类型为完成Bean的autowire                    if(mbd.getResolvedAutowireMode() == 1) {                        this.autowireByName(beanName, mbd, bw, hasInstAwareBpps1);                    }                    if(mbd.getResolvedAutowireMode() == 2) {                        this.autowireByType(beanName, mbd, bw, hasInstAwareBpps1);                    }                    pvs = hasInstAwareBpps1;                }                boolean hasInstAwareBpps2 = this.hasInstantiationAwareBeanPostProcessors();                boolean needsDepCheck1 = mbd.getDependencyCheck() != 0;                if(hasInstAwareBpps2 || needsDepCheck1) {                    PropertyDescriptor[] filteredPds1 = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);                    if(hasInstAwareBpps2) {                        Iterator var9 = this.getBeanPostProcessors().iterator();                        while(var9.hasNext()) {                            BeanPostProcessor bp = (BeanPostProcessor)var9.next();                            if(bp instanceof InstantiationAwareBeanPostProcessor) {                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;                                pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds1, bw.getWrappedInstance(), beanName);                                if(pvs == null) {                                    return;                                }                            }                        }                    }                    if(needsDepCheck1) {                        this.checkDependencies(beanName, mbd, filteredPds1, (PropertyValues)pvs);                    }                }// 对属性进行注入                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);  // --------------->            }        }    }    // 具体的对属性进行解析然后注入的过程    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {        if(pvs != null && !pvs.isEmpty()) {            MutablePropertyValues mpvs = null;            if(System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {                ((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());            }            List original;            if(pvs instanceof MutablePropertyValues) {                mpvs = (MutablePropertyValues)pvs;                if(mpvs.isConverted()) {                    try {                        bw.setPropertyValues(mpvs);                        return;                    } catch (BeansException var18) {                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);                    }                }                original = mpvs.getPropertyValueList();            } else {                original = Arrays.asList(pvs.getPropertyValues());            }            Object converter = this.getCustomTypeConverter();            if(converter == null) {                converter = bw;            }    // 注意这个BnDefinitionValueResolver对BeanDefinition的解析是在这个valueResolver中完成的            BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);    // 这里为解析值创建一个副本,副本的数据将会被注入到Bean中            ArrayList deepCopy = new ArrayList(original.size());            boolean resolveNecessary = false;            Iterator ex = original.iterator();            while(true) {                while(ex.hasNext()) {                    PropertyValue pv = (PropertyValue)ex.next();                    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 = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)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();                }// 这里是依赖注入发生的地方,会在BeanWrapperImpl中完成                try {                    bw.setPropertyValues(new MutablePropertyValues(deepCopy));  // ----------------->                    return;                } catch (BeansException var19) {                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);                }            }        }    }
    这里通过使用BeanDefinitionResolver来对BeanDefinition进行解析,然后注入到property中。
    下面到BeanDefinitionValueResolver中去看一下解析过程的实现,
------------------------------------------// class BeanDefinitionValueResolver     // 这个方法包含了所有对注入类型的处理    public Object resolveValueIfNecessary(Object argName, Object value) {// 这里对RuntimeBeanReference进行解析,该类是在对BeanDefinition进行解析时生成的数据对象        if(value instanceof RuntimeBeanReference) {            RuntimeBeanReference typedStringValue6 = (RuntimeBeanReference)value;            return this.resolveReference(argName, typedStringValue6);  // ------------->        } else if(value instanceof RuntimeBeanNameReference) {            String typedStringValue5 = ((RuntimeBeanNameReference)value).getBeanName();            typedStringValue5 = String.valueOf(this.doEvaluate(typedStringValue5));            if(!this.beanFactory.containsBean(typedStringValue5)) {                throw new BeanDefinitionStoreException("Invalid bean name \'" + typedStringValue5 + "\' in bean reference for " + argName);            } else {                return typedStringValue5;            }        } else if(value instanceof BeanDefinitionHolder) {            BeanDefinitionHolder typedStringValue4 = (BeanDefinitionHolder)value;            return this.resolveInnerBean(argName, typedStringValue4.getBeanName(), typedStringValue4.getBeanDefinition());        } else if(value instanceof BeanDefinition) {            BeanDefinition typedStringValue3 = (BeanDefinition)value;            String valueObject3 = "(inner bean)#" + ObjectUtils.getIdentityHexString(typedStringValue3);            return this.resolveInnerBean(argName, valueObject3, typedStringValue3);        } else if(value instanceof ManagedArray) { // 这里对ManagedArray            ManagedArray typedStringValue2 = (ManagedArray)value;            Class valueObject2 = typedStringValue2.resolvedElementType;            if(valueObject2 == null) {                String ex2 = typedStringValue2.getElementTypeName();                if(StringUtils.hasText(ex2)) {                    try {                        valueObject2 = ClassUtils.forName(ex2, this.beanFactory.getBeanClassLoader());                        typedStringValue2.resolvedElementType = valueObject2;                    } catch (Throwable var9) {                        throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error resolving array type for " + argName, var9);                    }                } else {                    valueObject2 = Object.class;                }            }            return this.resolveManagedArray(argName, (List)value, valueObject2);        } 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 typedStringValue1 = (Properties)value;            Properties valueObject1 = new Properties();            Object propKey;            Object propValue;            for(Iterator ex1 = typedStringValue1.entrySet().iterator(); ex1.hasNext(); valueObject1.put(propKey, propValue)) {                Entry propEntry = (Entry)ex1.next();                propKey = propEntry.getKey();                propValue = propEntry.getValue();                if(propKey instanceof TypedStringValue) {                    propKey = this.evaluate((TypedStringValue)propKey);                }                if(propValue instanceof TypedStringValue) {                    propValue = this.evaluate((TypedStringValue)propValue);                }            }            return valueObject1;        } else if(value instanceof TypedStringValue) {            TypedStringValue typedStringValue = (TypedStringValue)value;            Object valueObject = this.evaluate(typedStringValue);            try {                Class ex = this.resolveTargetType(typedStringValue);                return ex != null?this.typeConverter.convertIfNecessary(valueObject, ex):valueObject;            } catch (Throwable var10) {                throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Error converting typed String value for " + argName, var10);            }        } else {            return this.evaluate(value);        }    }    // 这里以一个例子    // 对RuntimeBeanReference类型的注入在resolveReference中,其他的去相应的方法    private Object resolveReference(Object argName, RuntimeBeanReference ref) {        try {    // 从RuntimeBeanReference取得reference的名字,这个类是在载入BeanDefinition时根据配置生成的            String ex = ref.getBeanName();            ex = String.valueOf(this.doEvaluate(ex));    // 如果ref是在双亲IoC容器中,那就到双亲IoC容器中去获取            if(ref.isToParent()) {                if(this.beanFactory.getParentBeanFactory() == null) {                    throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Can\'t resolve reference to bean \'" + ex + "\' in parent factory: no parent factory available");                } else {                    return this.beanFactory.getParentBeanFactory().getBean(ex);                }            } else {/* 在当前IoC容器中取得Bean,这里会触发一个getBean的过程如果依赖注入没有发生,这里会触发相应的依赖注入的发生*/                Object bean = this.beanFactory.getBean(ex);                this.beanFactory.registerDependentBean(ex, this.beanName);                return bean;            }        } catch (BeansException var5) {            throw new BeanCreationException(this.beanDefinition.getResourceDescription(), this.beanName, "Cannot resolve reference to bean \'" + ref.getBeanName() + "\' while setting " + argName, var5);        }    }
    在完成这个解析过程后,已经为依赖注入准备了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。
    依赖注入的发生是在BeanWrapper的setPropertyValues中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的,代码如下:
public interface PropertyAccessor {......    void setPropertyValue(PropertyValue var1) throws BeansException;......}--------------------//public abstract class AbstractPropertyAccessor extends TypeConverterSupport implements ConfigurablePropertyAccessor {    public void setPropertyValues(PropertyValues pvs) throws BeansException {        this.setPropertyValues(pvs, false, false);    }    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {......                this.setPropertyValue(pv);......    }    public void setPropertyValue(PropertyValue pv) throws BeansException {        this.setPropertyValue(pv.getName(), pv.getValue());    }    public abstract void setPropertyValue(String var1, Object var2) throws BeansException;-------------------------// public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor {    public void setPropertyValue(String propertyName, Object value) throws BeansException {......        nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));    }    protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {        String propertyName = tokens.canonicalName;        String actualName = tokens.actualName;        Object oldValue;        if(tokens.keys != null) {    //  设置tokens的索引和keys            AbstractNestablePropertyAccessor.PropertyTokenHolder ph = new AbstractNestablePropertyAccessor.PropertyTokenHolder();            ph.canonicalName = tokens.canonicalName;            ph.actualName = tokens.actualName;            ph.keys = new String[tokens.keys.length - 1];            System.arraycopy(tokens.keys, 0, ph.keys, 0, tokens.keys.length - 1);            try {// 该方法取得Bean中对注入对象的引用,比如Array,List,Map,Set等                oldValue = this.getPropertyValue(ph);            } catch (NotReadablePropertyException var20) {                throw new NotWritablePropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path \'" + propertyName + "\'", var20);            }            String ex = tokens.keys[tokens.keys.length - 1];            if(oldValue == null) {                if(!this.isAutoGrowNestedPaths()) {                    throw new NullValueInNestedPathException(this.getRootClass(), this.nestedPath + propertyName, "Cannot access indexed value in property referenced in indexed property path \'" + propertyName + "\': returned null");                }                int pce = tokens.canonicalName.lastIndexOf(91);                ph.canonicalName = tokens.canonicalName.substring(0, pce);                oldValue = this.setDefaultValue(ph);            }            Class cause;            Object typeDescriptor;            Object convertedMapValue;            AbstractNestablePropertyAccessor.PropertyHandler var27;            if(oldValue.getClass().isArray()) {  // 这里对Array进行注入                var27 = this.getLocalPropertyHandler(actualName);                cause = oldValue.getClass().getComponentType();                int mapValueType = Integer.parseInt(ex);                Object map = null;                try {                    if(this.isExtractOldValueForEditor() && mapValueType < Array.getLength(oldValue)) {                        map = Array.get(oldValue, mapValueType);                    }                    typeDescriptor = this.convertIfNecessary(propertyName, map, pv.getValue(), cause, var27.nested(tokens.keys.length));                    int convertedMapKey = Array.getLength(oldValue);                    if(mapValueType >= convertedMapKey && mapValueType < this.autoGrowCollectionLimit) {                        Class oldValue1 = oldValue.getClass().getComponentType();                        convertedMapValue = Array.newInstance(oldValue1, mapValueType + 1);                        System.arraycopy(oldValue, 0, convertedMapValue, 0, convertedMapKey);                        this.setPropertyValue(actualName, convertedMapValue);                        oldValue = this.getPropertyValue(actualName);                    }                    Array.set(oldValue, mapValueType, typeDescriptor);                } catch (IndexOutOfBoundsException var19) {                    throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid array index in property path \'" + propertyName + "\'", var19);                }            } else {                Object var37;                if(oldValue instanceof List) {  // 对List进行注入                    var27 = this.getPropertyHandler(actualName);                    cause = var27.getCollectionType(tokens.keys.length);                    List var31 = (List)oldValue;                    int var34 = Integer.parseInt(ex);                    typeDescriptor = null;                    if(this.isExtractOldValueForEditor() && var34 < var31.size()) {                        typeDescriptor = var31.get(var34);                    }                    var37 = this.convertIfNecessary(propertyName, typeDescriptor, pv.getValue(), cause, var27.nested(tokens.keys.length));                    int var38 = var31.size();                    if(var34 >= var38 && var34 < this.autoGrowCollectionLimit) {                        for(int var40 = var38; var40 < var34; ++var40) {                            try {                                var31.add((Object)null);                            } catch (NullPointerException var18) {                                throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Cannot set element with index " + var34 + " in List of size " + var38 + ", accessed using property path \'" + propertyName + "\': List does not support filling up gaps with null elements");                            }                        }                        var31.add(var37);                    } else {                        try {                            var31.set(var34, var37);                        } catch (IndexOutOfBoundsException var17) {                            throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Invalid list index in property path \'" + propertyName + "\'", var17);                        }                    }                } else {                    if(!(oldValue instanceof Map)) {  // 对Map进行注入                        throw new InvalidPropertyException(this.getRootClass(), this.nestedPath + propertyName, "Property referenced in indexed property path \'" + propertyName + "\' is neither an array nor a List nor a Map; returned value was [" + oldValue + "]");                    }                    var27 = this.getLocalPropertyHandler(actualName);                    cause = var27.getMapKeyType(tokens.keys.length);                    Class var32 = var27.getMapValueType(tokens.keys.length);                    Map var35 = (Map)oldValue;                    TypeDescriptor var36 = TypeDescriptor.valueOf(cause);                    var37 = this.convertIfNecessary((String)null, (Object)null, ex, cause, var36);                    Object var39 = null;                    if(this.isExtractOldValueForEditor()) {                        var39 = var35.get(var37);                    }                    convertedMapValue = this.convertIfNecessary(propertyName, var39, pv.getValue(), var32, var27.nested(tokens.keys.length));                    var35.put(var37, convertedMapValue);                }            }        } else {            AbstractNestablePropertyAccessor.PropertyHandler var25 = this.getLocalPropertyHandler(actualName);            if(var25 == null || !var25.isWritable()) {                if(pv.isOptional()) {                    if(logger.isDebugEnabled()) {                        logger.debug("Ignoring optional value for property \'" + actualName + "\' - property not found on bean class [" + this.getRootClass().getName() + "]");                    }                    return;                } else {                    throw this.createNotWritablePropertyException(propertyName);                }            }            oldValue = null;            PropertyChangeEvent var28;            try {                Object var26 = pv.getValue();                Object var29 = var26;                if(!Boolean.FALSE.equals(pv.conversionNecessary)) {                    if(pv.isConverted()) {                        var29 = pv.getConvertedValue();                    } else {                        if(this.isExtractOldValueForEditor() && var25.isReadable()) {                            try {                                oldValue = var25.getValue();                            } catch (Exception var21) {                                Exception var33 = var21;                                if(var21 instanceof PrivilegedActionException) {                                    var33 = ((PrivilegedActionException)var21).getException();                                }                                if(logger.isDebugEnabled()) {                                    logger.debug("Could not read previous value of property \'" + this.nestedPath + propertyName + "\'", var33);                                }                            }                        }                        var29 = this.convertForProperty(propertyName, oldValue, var26, var25.toTypeDescriptor());                    }                    pv.getOriginalPropertyValue().conversionNecessary = Boolean.valueOf(var29 != var26);                }// 这里取得注入属性的set方法,通过反射机制,把对象注入进去                var25.setValue(this.wrappedObject, var29);            } catch (TypeMismatchException var22) {                throw var22;            } catch (InvocationTargetException var23) {                var28 = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());                if(var23.getTargetException() instanceof ClassCastException) {                    throw new TypeMismatchException(var28, var25.getPropertyType(), var23.getTargetException());                }                Throwable var30 = var23.getTargetException();                if(var30 instanceof UndeclaredThrowableException) {                    var30 = var30.getCause();                }                throw new MethodInvocationException(var28, var30);            } catch (Exception var24) {                var28 = new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());                throw new MethodInvocationException(var28, var24);            }        }    }
    这样就完成了对各种Bean属性的依赖注入过程。
    在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入。从上面的几个递归过程中可以看到,这些递归都是以getBean为入口。一个递归是在上下文体系中查找需要的Bean和创建Bean的递归调用,另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也是触发对依赖Bean的创建和注入。在对Bean的属性进行依赖注入时,解析地过程也是一个递归的过程。这样根据依赖关系,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。
    在Bean创建和依赖注入完成以后,在IoC容器中建立起一系列依靠依赖关系联系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过IoC容器的相关接口方法,就可以非常方便地供上层应用使用了。

















0 0