论坛首页 Java企业应用论坛

Spring源代码解析(一):IOC容器

浏览 143578 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-06-28  
另外包含property value对象的BeanWrapperImpl怎么和容器中需要依赖他的bean相绑定呢?,上述的代码好像没有讲述到BeanDefinition与BeanWrapper的关系...
0 请登录后投票
   发表时间:2007-06-28  
bennyparlo 写道
不过对于上述的过程中也有问题.
就是说在org.springframework.beans.factory.xml.BeanDefinitonParserDelegate中
	public void parsePropertyElement(Element ele, BeanDefinition bd) {
		String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
		if (!StringUtils.hasLength(propertyName)) {
			error("Tag 'property' must have a 'name' attribute", ele);
			return;
		}
		this.parseState.push(new PropertyEntry(propertyName));
		try {
			if (bd.getPropertyValues().contains(propertyName)) {
				error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
				return;
			}
			Object val = parsePropertyValue(ele, bd, propertyName);
			PropertyValue pv = new PropertyValue(propertyName, val);
			parseMetaElements(ele, pv);
			pv.setSource(extractSource(ele));
			bd.getPropertyValues().addPropertyValue(pv);
		}
		finally {
			this.parseState.pop();
		}
	}

这里的property value只是个从xml中解析来的Element(字符流的封装),具体到了装配的时候,确可以被识别不同类型的对象(),这个包装的过程,在哪里实现的呢?

我想这里是处理对Property的依赖关系解析,比如如果是一个"bean ref",就会生成一个RunTimeReferenceBean,在代码里可以看到:
    public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
        String elementName = (propertyName != null) ?
                        "<property> element for property '" + propertyName + "'" :
                        "<constructor-arg> element";

        //这里取得这个Element的子元素值
        NodeList nl = ele.getChildNodes();
        Element subElement = null;
        for (int i = 0; i < nl.getLength(); i++) {
            if (nl.item(i) instanceof Element) {
                Element candidateEle = (Element) nl.item(i);
                //下面是对取得的子元素作的具体处理,取得subElement
                if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) {
                    // Keep going: we don't use this value for now.
                }
                else {
                    // Child element is what we're looking for.
                    if (subElement != null && !META_ELEMENT.equals(subElement.getTagName())) {
                        error(elementName + " must not contain more than one sub-element", ele);
                    }
                    subElement = candidateEle;
                }
            }
        }

        boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
        boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
        if ((hasRefAttribute && hasValueAttribute) ||
                ((hasRefAttribute || hasValueAttribute)) && subElement != null) {
            error(elementName +
                    " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
        }
        //如果这里取得的subElement是Ref bean,生成一个RuntimeBeanReference持有这个bean的名字,但是并不持有ref bean对象。
        if (hasRefAttribute) {
            String refName = ele.getAttribute(REF_ATTRIBUTE);
            if (!StringUtils.hasText(refName)) {
                error(elementName + " contains empty 'ref' attribute", ele);
            }
            RuntimeBeanReference ref = new RuntimeBeanReference(refName);
            ref.setSource(extractSource(ele));
            return ref;
        }
        else if (hasValueAttribute) {
            return ele.getAttribute(VALUE_ATTRIBUTE);
        }

        if (subElement == null) {
            // Neither child element nor "ref" or "value" attribute found.
            error(elementName + " must specify a ref or value", ele);
        }
        //这里处理其他类型的属性,比如我们看到的List,Map,Set等等
        return parsePropertySubElement(subElement, bd);
    }

在这里对定义的依赖关系已经在BeanDefinition里面持有了,但是还没有对依赖进行注入。看来依赖解析和具体的依赖注入Spring是分成了两个过程来做的。
0 请登录后投票
   发表时间:2007-06-28  
bennyparlo 写道

在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory中
	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * <p>Differentiates between default bean instantiation, use of a
	 * factory method, and autowiring a constructor.
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
			throws BeanCreationException {

		// 初始化被依赖的bean实例
		if (mbd.getDependsOn() != null) {
			for (int i = 0; i < mbd.getDependsOn().length; i++) {
				getBean(mbd.getDependsOn()[i]);
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "' with merged definition [" + mbd + "]");
		}

		// 判断当前bean的对象是否已经存在
		Class beanClass = resolveBeanClass(mbd, beanName);

		// Prepare method overrides.
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		String errorMessage = null;

		try {
			// Instantiate the bean.
			errorMessage = "BeanPostProcessor before instantiation of bean failed";

			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			if (beanClass != null &&
					!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Object bean = applyBeanPostProcessorsBeforeInstantiation(beanClass, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					return bean;
				}
			}

			// Instantiate the bean.
			errorMessage = "Instantiation of bean failed";

			BeanWrapper instanceWrapper = null;
			if (mbd.isSingleton()) {
				synchronized (getSingletonMutex()) {
					instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
				}
			}

			if (instanceWrapper == null) {
				instanceWrapper = createBeanInstance(beanName, mbd, args);
			}
			Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

			// Eagerly cache singletons to be able to resolve circular references
			// even when triggered by lifecycle interfaces like BeanFactoryAware.
			if (mbd.isSingleton() && this.allowCircularReferences &&
					isSingletonCurrentlyInCreation(beanName)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Eagerly caching bean '" + beanName +
							"' to allow for resolving potential circular references");
				}
				addSingleton(beanName, bean);
			}

			// Initialize the bean instance.
			errorMessage = "Initialization of bean failed";

			// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
			// state of the bean before properties are set. This can be used, for example,
			// to support styles of field injection.
			boolean continueWithPropertyPopulation = true;

			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) {
					BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
					if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
						if (!ibp.postProcessAfterInstantiation(bean, beanName)) {
							continueWithPropertyPopulation = false;
							break;
						}
					}
				}
			}

			if (continueWithPropertyPopulation) {
				populateBean(beanName, mbd, instanceWrapper);
			}

			Object originalBean = bean;
			bean = initializeBean(beanName, bean, mbd);

			if (!this.allowRawInjectionDespiteWrapping && originalBean != bean &&
					mbd.isSingleton() && hasDependentBean(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName,
						"Bean with name '" + beanName + "' has been injected into other beans " +
						getDependentBeans(beanName) + " in its raw version as part of a circular reference, " +
						"but has eventually been wrapped (for example as part of auto-proxy creation). " +
						"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.");
			}

			// Register bean as disposable, and also as dependent on specified "dependsOn" beans.
			registerDisposableBeanIfNecessary(beanName, originalBean, mbd);

			return bean;
		}

		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, errorMessage, ex);
		}
	}


没有找到这个createBean()是在什么时候别调用的 ..... ??? 有点奇怪
应该在loadBeanDefinition之后,但是没有找到调用它的地方......
0 请登录后投票
   发表时间:2007-06-28  
这个createBean被getBean方法调用了

public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException中调用了这个方法
0 请登录后投票
   发表时间:2007-06-28  
也就是说,当调用loadBeanDefinition后,或者说调用了BeanDefinitionRegistry.registerBeanDefinition()以后,所有的resource定义被封装成BeanDefiniton并且存放到beanDefinitionMap后,被客户端使用的时候,去做了这些个bean注入的操作.按我的理解,spring的ioc容器在启动的时候,加载资源定义,而bean依赖的被注入,还要等到具体被客户端使用的时候.
1 请登录后投票
   发表时间:2007-06-28  
bennyparlo 写道
这个createBean被getBean方法调用了

public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException中调用了这个方法

看到了,谢谢!!! 在AbstractFactoryBean中:
在AbstractFactoryBean中的getBean调用createBean
    public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException {
        final String beanName = transformedBeanName(name);
        Object bean = null;
            ........

            // 这里检查是不是在父工厂里这个bean
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    //这里调用父工厂的getBean
                    return ((AbstractBeanFactory) parentBeanFactory).getBean(nameToLookup, requiredType, args);
                }
                else if (args == null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    throw new NoSuchBeanDefinitionException(beanName,
                            "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments");
                }
            }

            this.alreadyCreated.add(beanName);

            final RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
            checkMergedBeanDefinition(mergedBeanDefinition, beanName, args);

            //这里调用bean的创建过程,也是依赖注入的地方,依赖解析已经完成放在BeanDefinition里面了
            if (mergedBeanDefinition.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mergedBeanDefinition, args);
                        }

          .........
    }

那看来bean的依赖注入是在第一次向容器请求bean的时候完成的,loadBeanDefinition只是把定义的bean和依赖解析了以后存到容器里。这个createBean和getBean要好好看看。

2 请登录后投票
   发表时间:2007-06-28  
bennyparlo 写道
也就是说,当调用loadBeanDefinition后,或者说调用了BeanDefinitionRegistry.registerBeanDefinition()以后,所有的resource定义被封装成BeanDefiniton并且存放到beanDefinitionMap后,被客户端使用的时候,去做了这些个bean注入的操作.按我的理解,spring的ioc容器在启动的时候,加载资源定义,而bean依赖的被注入,还要等到具体被客户端使用的时候.

完全同意!所以loadBeanDefinition和createBean是两个不同的过程,一个由容器启动的时候触发,一个由客户程序请求服务的时候触发!那大致可以看到启动的时候只是定位 - 读入 - 解析 - 注册,而最后的依赖注入还是要等到客户第一次请求bean的时候触发,如果有的bean不被请求,就不会被依赖注入。
1 请登录后投票
   发表时间:2007-06-29  
经过和bennyparlo同学的讨论和MSN,大致把IOC容器完成依赖注入的过程梳理了一遍。让我代笔结合源代码在下面给出分析,望大家多提意见!- 很多细节没法顾及到,慢慢来吧!先发一个广告 :)
我们大致可以看到Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。所以下面我们会详细的分析这个依赖注入的过程。
0 请登录后投票
   发表时间:2007-06-30  
我们大致可以看到Spring把loadBean和依赖注入分成两个基本的过程,一个是在启动容器的时候完成,建立起一系列 BeanDefinition,这些定义里面同时都包含了对bean依赖关系的描述,不过这里并没有对bean进行实例化,真正实例化的时候是在客户通过容器使用这些bean的时候 - 也就是getbean的时候。这个时候IOC容器根据需要会建立起一系列bean的实例和完成依赖注入。所以下面我们会详细的分析这个依赖注入的过程。
让我们先简单回顾IOC容器启动时候载入bean定义文件的过程,这个过程是通过BeanDefinitionReader来完成的,其中通过 loadBeanDefinition()来对定义文件进行解析和根据Spring定义的bean规则进行处理 - 事实上和Spring定义的bean规则相关的处理是在BeanDefinitionParserDelegate中完成的,完成这个处理需要得到用户定义的bean定义信息,这是在前面已经通过解析已经完成了的,这个处理过程的结果就是得到了一系列的BeanDefinition,这里不但包含了对 bean定义信息解析后的表示,同时还把和这个bean相关的依赖信息也保存了下来。那以后这些信息怎样被取得和被使用呢?在完成了这一系列的解析和处理之后,接着需要对对BeanFactoryRegistry的接口做一个回调,把这些BeanDefinition都放到一个HashMap - beanDefinitionMap里面,以后对这些信息的操作通过这个HashMap来完成。这样就完成了IOC启动过程中最重要的部分 - 依赖关系的解析,处理和建立,下面就是使用IOC容器的时候完成的依赖注入的行为。在AbstractBeanDefinition中我们看到有这些和依赖关系处理紧密相关的属性:
public abstract class AbstractBeanDefinition extends AttributeAccessorSupport implements BeanDefinition {
    ....... 
    private Object beanClass;
     ......
    //这个属性持有的这个bean的依赖属性,比如各种property的定义信息
    private MutablePropertyValues propertyValues;
    ......
}

很显然这些值都是在BeanDefinitionParserDelegate中设置的:
    public AbstractBeanDefinition parseBeanDefinitionElement(
            Element ele, String beanName, BeanDefinition containingBean) {
        //这里得到定义的类的名字 - 通过属性Class
        String className = null;
        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
            className = ele.getAttribute(CLASS_ATTRIBUTE);
        }
        .........
        try {
            this.parseState.push(new BeanEntry(beanName));
            //这里是生成BeanDefinition的地方,也是生成根据定义的class属性来生成bean JAVA对象的地方
            //以前我们已经分析过了,这里生成一个BeanDefinition , 它里面已经持有了生成的bean Java对象。
            AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
                    parent, className, getReaderContext().getReader().getBeanClassLoader());
            //下面是一系列对beandefinition的属性设置,依据是用户定义的bean定义信息,类似于用户定义的bean定义信息的读入
            if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
                // Spring 2.0 "scope" attribute
                bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
                if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
                    error("Specify either 'scope' or 'singleton', not both", ele);
                }
            }
            else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
                // Spring 1.x "singleton" attribute
                bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
            }
            ..........
            parseMetaElements(ele, bd);
            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            parseConstructorArgElements(ele, bd);
            //注意这里是对依赖关系,也就是bean对象属性的处理!
            parsePropertyElements(ele, bd);

            bd.setResourceDescription(getReaderContext().getResource().getDescription());
            bd.setSource(extractSource(ele));

            return bd;
            ................
}

在辅助类BeanDefinitionReaderUtils中对bean对象做了原始的创建:
    public static AbstractBeanDefinition createBeanDefinition(
            String parent, String className, ClassLoader classLoader) throws ClassNotFoundException {

        AbstractBeanDefinition bd = null;
        if (parent != null) {
            bd = new ChildBeanDefinition(parent);
        }
        else {
            bd = new RootBeanDefinition();
        }
        //这里创建了bean的JAVA对象,同时在beandefinition中持有
        if (className != null) {
            if (classLoader != null) {
                bd.setBeanClass(ClassUtils.forName(className, classLoader));
            }
            else {
                bd.setBeanClassName(className);
            }
        }
        return bd;
    }

下面我们分析parsePropertyElements(ele, bd)看看那些属性依赖关系是怎样处理的:
    public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
        //这里取得所有定义的属性定义
        NodeList nl = beanEle.getChildNodes();
        //很显然,需要一个一个的处理
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element && DomUtils.nodeNameEquals(node, PROPERTY_ELEMENT)) {
                parsePropertyElement((Element) node, bd);
            }
        }

    public void parsePropertyElement(Element ele, BeanDefinition bd) {
        //这里得到属性定义的名字
        String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
        if (!StringUtils.hasLength(propertyName)) {
            error("Tag 'property' must have a 'name' attribute", ele);
            return;
        }
        this.parseState.push(new PropertyEntry(propertyName));
        try {
            //判断是不是已经有重名的属性定义
            if (bd.getPropertyValues().contains(propertyName)) {
                error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
                return;
            }
            //这里根据属性的名字对属性的定义进行具体的解析,结果放在PropertyValue对象里面
            //这里包含了对各种属性类型的解析,比如List,Map,Set,当然还有reference bean等等,
            //这个propertyValue是连接和表示各个bean之间依赖关系的桥梁
            Object val = parsePropertyValue(ele, bd, propertyName);
            PropertyValue pv = new PropertyValue(propertyName, val);
            parseMetaElements(ele, pv);
            pv.setSource(extractSource(ele));
            //最后把这个解析的结果,也就是生成的Property对象放到beanDefinition里面去
            bd.getPropertyValues().addPropertyValue(pv);
        }
        finally {
            this.parseState.pop();
        }
    }

我们看看具体的对各种属性定义的解析,在parsePropertyValue函数中:
    public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
        String elementName = (propertyName != null) ?
                        "<property> element for property '" + propertyName + "'" :
                        "<constructor-arg> element";

        // Should only have one child element: ref, value, list, etc.
        //这里根据DOM取得需要分析的属性定义
        NodeList nl = ele.getChildNodes();
        Element subElement = null;
        for (int i = 0; i < nl.getLength(); i++) {
            if (nl.item(i) instanceof Element) {
                Element candidateEle = (Element) nl.item(i);
                if (DESCRIPTION_ELEMENT.equals(candidateEle.getTagName())) {
                    // Keep going: we don't use this value for now.
                }
                else {
                    // Child element is what we're looking for.
                    if (subElement != null && !META_ELEMENT.equals(subElement.getTagName())) {
                        error(elementName + " must not contain more than one sub-element", ele);
                    }
                    subElement = candidateEle;
                }
            }
        }

        boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
        boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
        if ((hasRefAttribute && hasValueAttribute) ||
                ((hasRefAttribute || hasValueAttribute)) && subElement != null) {
            error(elementName +
                    " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
        }
        if (hasRefAttribute) {
            //这里是对ref属性的解析,称称一个RuntimeBeanReference对象,
            //这个RuntimeBeanReference很简单,只是保持beanName,toParent,source三个属性信息,对记录依赖关系已经足够了
            String refName = ele.getAttribute(REF_ATTRIBUTE);
            if (!StringUtils.hasText(refName)) {
                error(elementName + " contains empty 'ref' attribute", ele);
            }
            RuntimeBeanReference ref = new RuntimeBeanReference(refName);
            ref.setSource(extractSource(ele));
            return ref;
        }
        else if (hasValueAttribute) {
            return ele.getAttribute(VALUE_ATTRIBUTE);
        }

        if (subElement == null) {
            // Neither child element nor "ref" or "value" attribute found.
            error(elementName + " must specify a ref or value", ele);
        }
        //这里对各种其他属性值进行处理,比如List,Map,Set等等
        return parsePropertySubElement(subElement, bd);
    }

比如我们举个例子看看对List属性的解析,也是生成一个对应的List对象,里面记录了相关的定义信息,
    public List parseListElement(Element collectionEle, BeanDefinition bd) {
        String defaultTypeClassName = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
        NodeList nl = collectionEle.getChildNodes();
        ManagedList list = new ManagedList(nl.getLength());
        list.setSource(extractSource(collectionEle));
        list.setMergeEnabled(parseMergeAttribute(collectionEle));
        //这里对List的各个子属性进行处理,结果放到这个List,然后返回到beandefinition中以后可以使用。
        for (int i = 0; i < nl.getLength(); i++) {
            if (nl.item(i) instanceof Element) {
                Element ele = (Element) nl.item(i);
                list.add(parsePropertySubElement(ele, bd, defaultTypeClassName));
            }
        }
        return list;
    }

这样就把相应的属性对象都解析完,而且都放到了beandefinition中去,这个beandefinition是以后容器进行依赖注入和依赖管理的最主要的数据结构。
2 请登录后投票
   发表时间:2007-06-30  
有了上面的准备,我们可以看看依赖关系是怎样被注入的,我们知道IOC容器在loadBeanDefinition的时候只是完成了bean定义的解析和向IOC容器的注册,这个时候并没有对依赖的实现注入,具体的注入过程是在客户程序向IOC容器要求bean的时候完成的,具体的过程我们在代码中可以看到 - 在AbstractFactoryBean中:
    public Object getBean(String name, Class requiredType, final Object[] args) throws BeansException {
        final String beanName = transformedBeanName(name);
        Object bean = null;

        // Eagerly check singleton cache for manually registered singletons.
        // 这里先从缓存中去取,处理那些已经被创建过的单件模式的bean,对这种bean的请求不需要重复的去创建
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
            .......
            }
            else {
            .......
            }
            if (containsBeanDefinition(beanName)) {
                RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
                bean = getObjectForBeanInstance(sharedInstance, name, mergedBeanDefinition);
            }
            else {
                bean = getObjectForBeanInstance(sharedInstance, name, null);
            }
        }

        else {
            // Fail if we're already creating this singleton instance:
            // We're assumably within a circular reference.
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            //这里检查是否能在当前的工厂中取到我们需要的bean,如果在当前的工厂中取不到,则到父工厂取,如果一直取不到
            //那就顺着工厂链一直向上查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);

                // 这里调用父工厂的getbean取需要的bean
                // 这里有一个迭代,在父工厂中也会重复这么一个getbean的过程。
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    // Delegation to parent with args only possible for AbstractBeanFactory.                 
                    return ((AbstractBeanFactory) parentBeanFactory).getBean(nameToLookup, requiredType, args);
                }
                else if (args == null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {
                    throw new NoSuchBeanDefinitionException(beanName,
                            "Cannot delegate to parent BeanFactory because it does not supported passed-in arguments");
                }
            }
            //把这个已经被要求过的bean记录下来,因为第一次要求bean的时候往往就是依赖被容器对bean进行注入的时候。
            this.alreadyCreated.add(beanName);          
           
            final RootBeanDefinition mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
            checkMergedBeanDefinition(mergedBeanDefinition, beanName, args);

            // Create bean instance.
            //这里是根据beandefinition来创建bean和完成依赖注入的地方。
            if (mergedBeanDefinition.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory() {
                    public Object getObject() throws BeansException {
                        try {
                            //注意这个createBean,是创建bean同时完成依赖注入的地方。
                            return createBean(beanName, mergedBeanDefinition, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, mergedBeanDefinition);
            }
            //这里是处理prototype类型的bean请求的地方
            else if (mergedBeanDefinition.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    //每次请求,直接通过createBean来创建
                    prototypeInstance = createBean(beanName, mergedBeanDefinition, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, mergedBeanDefinition);
            }
         ........
         return bean;
    }

具体的bean创建过程和依赖关系的注入在createBean中,这个方法在
AbstractAutowireCapableBeanFactory中给出了实现:
    protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition, Object[] args)
            throws BeanCreationException {

        // Guarantee initialization of beans that the current one depends on.
        // 这里对取得当前bean的所有依赖bean,确定能够取得这些已经被确定的bean,如果没有被创建,那么这个createBean会被这些IOC
        // getbean时创建这些bean
        if (mergedBeanDefinition.getDependsOn() != null) {
            for (int i = 0; i < mergedBeanDefinition.getDependsOn().length; i++) {
                getBean(mergedBeanDefinition.getDependsOn()[i]);
            }
        }
      
            ........

            // 这里是实例化bean对象的地方,注意这个BeanWrapper类,是对bean操作的主要封装类
            if (instanceWrapper == null) {
                instanceWrapper = createBeanInstance(beanName, mergedBeanDefinition, args);
            }
            Object bean = instanceWrapper.getWrappedInstance();
            ......
            //这个populate方法,是对已经创建的bean实例进行依赖注入的地方,会使用到在loadBeanDefinition的时候得到的那些propertyValue来对bean进行注入。
            if (continueWithPropertyPopulation) {
                populateBean(beanName, mergedBeanDefinition, instanceWrapper);
            }
           
            //这里完成客户自定义的对bean的一些初始化动作
            Object originalBean = bean;
            bean = initializeBean(beanName, bean, mergedBeanDefinition);
            // Register bean as disposable, and also as dependent on specified "dependsOn" beans.
            registerDisposableBeanIfNecessary(beanName, originalBean, mergedBeanDefinition);

            return bean;
        }

       .........
    }


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics