Spring技术内幕——依赖注入

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


下面从DefaultListableBeanFactory的基类AbstractBeanFactory入手去看看getBean的实现:

//--------------------------------------------------------------------  
// 这里是对 BeanFactory接口的实现,比如getBean接口方法  
// 这些getBean接口方法最终是通过调用doGetBean来实现的  
//--------------------------------------------------------------------  
public Object getBean(String name) throws BeansException {  
    return doGetBean(name, null, null, false);  
}  
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {  
    return doGetBean(name, requiredType, null, false);  
}  
public Object getBean(String name, Object... args) throws BeansException {  
    return doGetBean(name, null, args, false);  
}  
public <T> T getBean(String name, Class<T> requiredType, Object[] args)  
throws BeansException {  
    return doGetBean(name, requiredType, args, false);  
}  
//这里是实际取得Bean的地方,也是触发依赖注入发生的地方  
protected <T> T doGetBean(  
        final String name, final Class<T> requiredType, final Object[] args, boolean  
typeCheckOnly)  
        throws BeansException {  
    final String beanName = transformedBeanName(name);  
    Object bean;  
    //先从缓存中取得Bean,处理那些已经被创建过的单件模式的Bean,对这种Bean的请求不需要  
    //重复地创建  
    Object sharedInstance = getSingleton(beanName);  
    if (sharedInstance != null && args == null) {  //这一段只是写日志
        if (logger.isDebugEnabled()) {  
            if (isSingletonCurrentlyInCreation(beanName)) {  
                logger.debug("Returning eagerly cached instance of singleton bean  
                '" + beanName +  
                "' that is not fully initialized yet - a consequence  
                of a circular reference");  
            }  
            else {  
                logger.debug("Returning cached instance of singleton bean '" +  
             beanName + "'");  
            }  
        }  
    /*这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,以取得FactoryBean的生产结果, BeanFactory和FactoryBean的区别已经在前面讲过,这个过程在后面还会详细地分析*/     
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
    }  
    else {  
        if (isPrototypeCurrentlyInCreation(beanName)) {  
            throw new BeanCurrentlyInCreationException(beanName);  
        }  
    /*这里对IoC容器中的BeanDefintion是否存在进行检查,检查是否能在当前的BeanFactory中取得需要的Bean。如果在当前的工厂中取不到,则到双亲BeanFactory中去取;如果当前的双亲工厂取不到,那就顺着双亲BeanFactory链一直向上查找*/  
        BeanFactory parentBeanFactory = getParentBeanFactory();  
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
            String nameToLookup = originalBeanName(name);  
            if (args != null) {  
                return (T) parentBeanFactory.getBean(nameToLookup, args);  
            }  
            else {  
                return parentBeanFactory.getBean(nameToLookup, requiredType);  
            }  
        }  
        if (!typeCheckOnly) {  
            markBeanAsCreated(beanName);  
        }  
        //这里根据Bean的名字取得BeanDefinition  
        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
        checkMergedBeanDefinition(mbd, beanName, args);  
        //获取当前Bean的所有依赖Bean,这样会触发getBean的递归调用,直到取到一个没有任何依赖的Bean为止  
        String[] dependsOn = mbd.getDependsOn();  
        if (dependsOn != null) {  
            for (String dependsOnBean : dependsOn) {  
                getBean(dependsOnBean);  
                registerDependentBean(dependsOnBean, beanName);  
            }  
        }  
        /*这里通过调用createBean方法创建Singleton bean的实例,这里有一个回调函数getObject,会在getSingleton中调用ObjectFactory的createBean*/  
        //下面会进入到createBean中进行详细分析  
        if (mbd.isSingleton()) {  
            sharedInstance = getSingleton(beanName, new ObjectFactory() {  
                public Object getObject() throws BeansException {  
                try {  
                    return createBean(beanName, mbd, args);  
                }  
                catch (BeansException ex) {  
                    destroySingleton(beanName);  
                    throw ex;  
                }  
            }  
            });  
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
        }  
        //这里是创建prototype bean的地方  
        else if (mbd.isPrototype()) {  
            Object prototypeInstance = null;  
            try {  
                beforePrototypeCreation(beanName);  
                prototypeInstance = createBean(beanName, mbd, args);  
            }  
            finally {  
                afterPrototypeCreation(beanName);  
            }  
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
        }  
        else {  
            String scopeName = mbd.getScope();  
            final Scope scope = this.scopes.get(scopeName);  
            if (scope == null) {  
                throw new IllegalStateException("No Scope registered for scope '"  
                + scopeName + "'");  
            }  
            try {  
                Object scopescopedInstance = scope.get(beanName, new ObjectFactory() {  
                    public Object getObject() throws BeansException {  
                        beforePrototypeCreation(beanName);  
                        try {  
                            return createBean(beanName, mbd, args);  
                        }  
                        finally {  
                            afterPrototypeCreation(beanName);  
                            }  
                    }  
                });  
                bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
            }  
            catch (IllegalStateException ex) {  
                throw new BeanCreationException(beanName,  
                        "Scope '" + scopeName + "' 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",ex);  
            }  
        }  
    }  
    // 这里对创建的Bean进行类型检查,如果没有问题,就返回这个新创建的Bean,这个Bean已经  
    //是包含了依赖关系的Bean  
    if (requiredType != null && bean != null && !requiredType.  
    isAssignableFrom(bean.getClass())) {  
    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());  
    }  
    return (T) bean;  
} 

在这里我们看到,与依赖注入关系特别密切的方法有createBeanInstance和populateBean,下面分别介绍这两个方法。在createBeanInstance中生成了Bean所包含的Java对象,这个对象的生成有很多种不同的方式,可以通过工厂方法生成,也可以通过容器的autowire特性生成,这些生成方式都是由相关的BeanDefinition来指定的。如代码清单2-24所示,可以看到不同生成方式对应的实现。

代码清单2-24   Bean包含的Java对象的生成

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition  
mbd, Object[] args) {  
// 确认需要创建的Bean实例的类可以实例化  
Class beanClass = resolveBeanClass(mbd, beanName);  
//这里使用工厂方法对Bean进行实例化  
if (mbd.getFactoryMethodName() != null)  {  
    return instantiateUsingFactoryMethod(beanName, mbd, args);  
}  
if (mbd.resolvedConstructorOrFactoryMethod != null) {  
    if (mbd.constructorArgumentsResolved) {  
        return autowireConstructor(beanName, mbd, null, args);  
    }  
    else {  
        return instantiateBean(beanName, mbd);  
    }  
}  
// 使用构造函数进行实例化  
Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);  
if (ctors != null ||  
        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||  
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {  
    return autowireConstructor(beanName, mbd, ctors, args);  
    }  
    // 使用默认的构造函数对Bean进行实例化  
    return instantiateBean(beanName, mbd);  
}  
//最常见的实例化过程instantiateBean  
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {  
//使用默认的实例化策略对Bean进行实例化,默认的实例化策略是  
//CglibSubclassingInstantiationStrategy,也就是使用CGLIB来对Bean进行实例化  
    //接着再看CglibSubclassingInstantiationStrategy的实现  
    try {  
        Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);  
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);  
        initBeanWrapper(bw);  
        return bw;  
    }  
    catch (Throwable ex) {  
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,  
        "Instantiation of bean failed", ex);  
    }  
} 
这里用cglib对Bean进行实例化。CGLIB是一个常用的字节码生成器的类库,它提供了一系列的API来提供生成和转换Java字节码的功能。在IoC容器中,要了解怎样使用cglib来生成Bean对象,需要看一下SimpleInstantiationStrategy类。这个Strategy是Spring用来生成Bean对象的默认类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,它使用了JVM的反射功能,一种是通过前面提到的cglib来生成。
-----------------------------------------------------------------------------------------------

到这里已经分析了实例化Bean对象的整个过程。在实例化Bean对象生成的基础上,再介绍一下Spring是怎样对这些对象进行处理的,也就是Bean对象生成以后,怎样把这些Bean对象的依赖关系设置好,完成整个依赖注入过程。这个过程涉及对各种Bean对象的属性的处理过程(即依赖关系处理的过程),这些依赖关系处理的依据就是已经解析得到的BeanDefinition。要详细了解这个过程,需要回到前面的populateBean方法。

protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) {  
//这里取得在BeanDefinition中设置的property值,这些property来自对BeanDefinition的解析  
//具体的解析过程可以参看对载入和解析BeanDefinition的分析  
    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;  
        }  
    }  
    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;  
    }  
    //开始进行依赖注入过程,先处理autowire的注入  
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||  
        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
        MutablePropertyValues newnewPvs = new MutablePropertyValues(pvs);  
        // 这里是对autowire注入的处理,可以根据Bean的名字或者类型,  
        //来完成Bean的autowire  
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
            autowireByName(beanName, mbd, bw, newPvs);  
        }  
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {  
            autowireByType(beanName, mbd, bw, newPvs);  
        }  
        pvs = newPvs;  
    }  
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.  
    DEPENDENCY_CHECK_NONE);  
    if (hasInstAwareBpps || needsDepCheck) {  
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);  
        if (hasInstAwareBpps) {  
            for (BeanPostProcessor bp : getBeanPostProcessors()) {  
                if (bp instanceof InstantiationAwareBeanPostProcessor) {  
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBean  
                    PostProcessor) bp;  
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds,  
                    bw.getWrappedInstance(), beanName);  
                    if (pvs == null) {  
                        return;  
                    }  
                }  
            }  
        }  
        if (needsDepCheck) {  
            checkDependencies(beanName, mbd, filteredPds, pvs);  
        }  
    }  
    //对属性进行注入  
    applyPropertyValues(beanName, mbd, bw, pvs);  
}  
//通过applyPropertyValues了解具体的对属性行进行解析然后注入的过程  
protected void applyPropertyValues(String beanName, BeanDefinition mbd,  
BeanWrapper bw, PropertyValues pvs) {  
    if (pvs == null || pvs.isEmpty()) {  
        return;  
    }  
    MutablePropertyValues mpvs = null;  
    List<PropertyValue> original;  
    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对BeanDefinition的解析是在  
    //这个valueResolver中完成的  
    BeanDefinitionValueResolver valueResolver = new   
    BeanDefinitionValueResolver(this, beanName, mbd, converter);  
    //这里为解析值创建一个副本,副本的数据将会被注入到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();  
            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 (originalValue instanceof TypedStringValue && convertible &&  
                !(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));  
    }  
    catch (BeansException ex) {  
        throw new BeanCreationException(  
              mbd.getResourceDescription(), beanName, "Error setting   
              property values", ex);  
    }  
} 

这里通过使用BeanDefinitionResolver来对BeanDefinition进行解析,然后注入到property中。

在完成这个解析过程后,已经为依赖注入准备好了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。依赖注入的发生是在BeanWrapper的setPropertyValues中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的。

这样就完成了对各种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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值