spring源码解析-从xml配置文件中获取bean

来源:互联网 发布:cdn.bootcss.com 知乎 编辑:程序博客网 时间:2024/04/29 19:27

在spring的实际应用中,我们经常将bean定义在xml的配置文件当中,那么,spring是如何从xml加载bean的呢?今天我们将从源码的层面进行简单的解读。假设,我们有如下一个spring的配置文件,这是我从一个dubbo的demo中获取的。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">    <!-- 提供方应用信息,用于计算依赖关系 -->    <dubbo:application name="hello-world-app"  />    <!-- 使用zookeeper注册中心暴露服务地址 -->    <dubbo:registry protocol="zookeeper" address="172.23.28.51:2181,172.23.28.52:2181,172.23.28.53:2181" version="1.0"/>    <!-- 用dubbo协议在20880端口暴露服务 -->    <dubbo:protocol name="dubbo" port="20880" />    <!-- 声明需要暴露的服务接口 -->    <dubbo:service interface="com.cmcc.hy.dubbo.DemoService" ref="helloService"  id="helloServiceDubbo"/>    <dubbo:service interface="com.cmcc.hy.dubbo.DemoService" ref="guyService" id="guyServiceDubbo" />    <!-- 和本地bean一样实现服务 -->    <bean id="helloService" class="com.cmcc.hy.dubbo.HelloServiceImpl" />    <bean id="guyService" class="com.cmcc.hy.dubbo.GuyServiceImpl"/>    <beans>        <bean id = "testService" class="com.cmcc.hy.dubbo.HelloServiceImpl"/>    </beans></beans>

在spring 3.1的版本之前,我们可以使用XmlBeanFactory加载xml配置文件,比如:

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("dubbo-provider.xml"));factory.getBean("guyService");

构造函数中xml配置文件作为Resource载入。

在spring 3.1之后的版本,建议使用DefaultListableBeanFactoryXmlBeanDefinitionReader来从xml中加载bean。DefaultListableBeanFactoryListableBeanFactory接口和BeanDefinitionRegistry接口的默认实现,XmlBeanDefinitionReader顾名思义,从xml中解析bean的定义。使用这两个类,加载我们前述的配置文件则可以使用下面的代码:

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);reader.loadBeanDefinitions(new ClassPathResource("dubbo-provider.xml"));Object bean = factory.getBean("guyService");

从代码看,加载的核心代码是在第三行和第四行,我们进入到loadBeanDefinitions方法看它的源码,里面加入了一些我自己的注解:

    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {        //对Recource进行编码        return loadBeanDefinitions(new EncodedResource(resource));    }    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {        Assert.notNull(encodedResource, "EncodedResource must not be null");        if (logger.isInfoEnabled()) {            logger.info("Loading XML bean definitions from " + encodedResource.getResource());        }        //this.resourcesCurrentlyBeingLoaded是ThreadLocal的本地线程变量,存储当前在load的resources        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();        if (currentResources == null) {            currentResources = new HashSet<EncodedResource>(4);            this.resourcesCurrentlyBeingLoaded.set(currentResources);        }        //检测是否是在循环load        if (!currentResources.add(encodedResource)) {            throw new BeanDefinitionStoreException(                    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");        }        try {            InputStream inputStream = encodedResource.getResource().getInputStream();            try {                InputSource inputSource = new InputSource(inputStream);                if (encodedResource.getEncoding() != null) {                    inputSource.setEncoding(encodedResource.getEncoding());                }                //真正的load从此进入                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());            }            finally {                inputStream.close();            }        }        catch (IOException ex) {            throw new BeanDefinitionStoreException(                    "IOException parsing XML document from " + encodedResource.getResource(), ex);        }        finally {            currentResources.remove(encodedResource);            if (currentResources.isEmpty()) {                this.resourcesCurrentlyBeingLoaded.remove();            }        }    }

我们再仔细看一下doLoadBeanDefinitions的源码:

    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)            throws BeanDefinitionStoreException {        try {            //解析resource获取Document            Document doc = doLoadDocument(inputSource, resource);            //注册BeanDefinition            return registerBeanDefinitions(doc, resource);        }        catch (BeanDefinitionStoreException ex) {            throw ex;        }        catch (SAXParseException ex) {            throw new XmlBeanDefinitionStoreException(resource.getDescription(),                    "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);        }        catch (SAXException ex) {            throw new XmlBeanDefinitionStoreException(resource.getDescription(),                    "XML document from " + resource + " is invalid", ex);        }        catch (ParserConfigurationException ex) {            throw new BeanDefinitionStoreException(resource.getDescription(),                    "Parser configuration exception parsing XML from " + resource, ex);        }        catch (IOException ex) {            throw new BeanDefinitionStoreException(resource.getDescription(),                    "IOException parsing XML document from " + resource, ex);        }        catch (Throwable ex) {            throw new BeanDefinitionStoreException(resource.getDescription(),                    "Unexpected exception parsing XML document from " + resource, ex);        }    }    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {        //创建BeanDefinition的Document Reader        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();        //获取已经解析了的BeanDefiniton的数目        int countBefore = getRegistry().getBeanDefinitionCount();        //使用reource创建reader的上下文,注册当前的BeanDefinition        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));        return getRegistry().getBeanDefinitionCount() - countBefore;    }    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {        this.readerContext = readerContext;        logger.debug("Loading bean definitions");        Element root = doc.getDocumentElement();        //真正register BeanDefinition的入口        doRegisterBeanDefinitions(root);    }    protected void doRegisterBeanDefinitions(Element root) {        //嵌套的<beans>将递归调用这个方法,为了能够传播和保存<beans>的default-*属性,需要跟踪当前的委托        //初始的委托为null        BeanDefinitionParserDelegate parent = this.delegate;        //创建委托,并初始化default-*属性        this.delegate = createDelegate(getReaderContext(), root, parent);        if (this.delegate.isDefaultNamespace(root)) {            String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);            if (StringUtils.hasText(profileSpec)) {                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);                if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {                    if (logger.isInfoEnabled()) {                        logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +                                "] not matching: " + getReaderContext().getResource());                    }                    return;                }            }        }        //供子类使用,作为前置处理        preProcessXml(root);        //使用委托从root节点解析BeanDefinition        parseBeanDefinitions(root, this.delegate);        //供子类使用,作为后置处理        postProcessXml(root);        this.delegate = parent;    }    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {        //判断是否是默认的namespace        if (delegate.isDefaultNamespace(root)) {            NodeList nl = root.getChildNodes();            for (int i = 0; i < nl.getLength(); i++) {                Node node = nl.item(i);                if (node instanceof Element) {                    Element ele = (Element) node;                    if (delegate.isDefaultNamespace(ele)) {                        //解析默认的element                        parseDefaultElement(ele, delegate);                    }                    else {                        //解析自定义的element                        delegate.parseCustomElement(ele);                    }                }            }        }        else {            delegate.parseCustomElement(root);        }    }    

我们这次看一下解析默认element的parseDefaultElement方法:

    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {        //处理import节点        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {            importBeanDefinitionResource(ele);        }        //处理alias节点        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {            processAliasRegistration(ele);        }        //处理bean节点        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {            processBeanDefinition(ele, delegate);        }        //处理嵌套的beans节点        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {            // 此处会引入之前所说的递归            doRegisterBeanDefinitions(ele);        }    }

此处,我们主要看一下加载bean的方法:

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {        //解析element,获得一个BeanDefinitionHolder作为BeanDefinition的容器,内有BeanDefinition、name和//alias,这个方法详细解析了对应element的各个attribute,如autowired,scope等;同时,还解析了其的子节//点,如constructor,property等        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);        if (bdHolder != null) {            //对BeanDefinitionHolder进行装饰,作为最终要注册进BeanFactory的实例,此处装饰的作用是解析一些自//定义的标签            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);            try {                // 此处将BeanDefinitionHolder注册进入registry,也就是示例代码中的//DefaultListableBeanFactory                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());            }            catch (BeanDefinitionStoreException ex) {                getReaderContext().error("Failed to register bean definition with name '" +                        bdHolder.getBeanName() + "'", ele, ex);            }            // Send registration event.            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));        }    }

DefaultListableBeanFactory维护了一个beanDefinitionMap,其键值对形式为beanName->BeanDefinition,这是一个ConcurrentHashMap。注意,这个map维护的只是BeanDefinition,并不是我们要获取的bean对象,这两者是有区别的,bean对象的获取需要调用BeanFactory接口的getBean方法。spring中维护了大量的ConcurrentHashMap,作为本地缓存。至此,完成了整个XmlBeanDefinitionReader的loadBeanDefinitions方法。


在解读DefaultListableBeanFactory的getBean(String name)方法之前,我们看一下
接下来,我们看看DefaultListableBeanFactory的getBean(String name)方法,这个方法用于获取真正的我们使用的Bean Object:

    public Object getBean(String name) throws BeansException {        return doGetBean(name, null, null, false);    }    protected <T> T doGetBean(            final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)            throws BeansException {        //转换beanName,这里主要是将FactoryBean的前缀&符号去除,此处不做详细的解释        final String beanName = transformedBeanName(name);        Object bean;        // 早期检查,尝试从缓存中获取实例,此处为了防止循环依赖的问题,会尝试从earlySingletonObjects中获取实例,没有的话再从ObjectFactory中获取,再将之放入earlySingletonObjects,此时获取到的对象是不完整的,即它的依赖还未创建完成        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 + "'");                }            }            //这个方法其实是获取到真正需要使用的bean,如果要获取的bean实现了FactoryBean接口,那么,获取到的bean其实是FactoryBean中getObject方法的吐出的object            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);        }        else {            // Fail if we're already creating this bean instance:            // We're assumably within a circular reference.            if (isPrototypeCurrentlyInCreation(beanName)) {                throw new BeanCurrentlyInCreationException(beanName);            }            //检查父类的BeanFactory            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {                // Not found -> check parent.                String nameToLookup = originalBeanName(name);                if (args != null) {                    // Delegation to parent with explicit args.                    return (T) parentBeanFactory.getBean(nameToLookup, args);                }                else {                    // No args -> delegate to standard getBean method.                    return parentBeanFactory.getBean(nameToLookup, requiredType);                }            }            if (!typeCheckOnly) {                //标记bean为已创建,实际是在alreadyCreated加入对应的beanName                markBeanAsCreated(beanName);            }            try {                //将GenericBeanDefinition装换为RootBeanDefinition                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);                //检查RootBeanDefinition是否为抽象                checkMergedBeanDefinition(mbd, beanName, args);                // 要保证depend-on属性的bean先被初始化                String[] dependsOn = mbd.getDependsOn();                if (dependsOn != null) {                    for (String dep : dependsOn) {                        if (isDependent(beanName, dep)) {                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");                        }                        registerDependentBean(dep, beanName);                        getBean(dep);                    }                }                // 以下是创建bean的过程                //scope为singleton的创建                if (mbd.isSingleton()) {                    //此处定义了一个内部类,实现ObjectFactory接口,ObjectFactory和FactoryBean都有getObject方法,前者重在创建object自身,后者重在获取其内部管理的object,此处的getObject方法的实现是调用了AbstractAutowireCapableBeanFactory中的createBean方法,为什么?因为DefaultListableBeanFactory是AbstractAutowireCapableBeanFactory的子类                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {                        @Override                        public Object getObject() throws BeansException {                            try {                                return createBean(beanName, mbd, args);                            }                            catch (BeansException ex) {                                // Explicitly remove instance from singleton cache: It might have been put there                                // eagerly by the creation process, to allow for circular reference resolution.                                // Also remove any beans that received a temporary reference to the bean.                                destroySingleton(beanName);                                throw ex;                            }                        }                    });                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);                }                //scope为prototype的创建,此文不详细讲解                else if (mbd.isPrototype()) {                    // It's a prototype -> create a new instance.                    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 name '" + scopeName + "'");                    }                    try {                        Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {                            @Override                            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);                    }                }            }            catch (BeansException ex) {                cleanupAfterBeanCreationFailure(beanName);                throw ex;            }        }        // Check if required type matches the type of the actual bean instance.        if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {            try {                return getTypeConverter().convertIfNecessary(bean, requiredType);            }            catch (TypeMismatchException ex) {                if (logger.isDebugEnabled()) {                    logger.debug("Failed to convert bean '" + name + "' to required type '" +                            ClassUtils.getQualifiedName(requiredType) + "'", ex);                }                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());            }        }        return (T) bean;    }   

从注释中看到,我们创建对象的过程是在getSingleton(String beanName, ObjectFactory

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {        Assert.notNull(beanName, "'beanName' must not be null");        synchronized (this.singletonObjects) {            //在此尝试从缓存中获取bean            Object singletonObject = this.singletonObjects.get(beanName);            if (singletonObject == null) {                if (this.singletonsCurrentlyInDestruction) {                    throw new BeanCreationNotAllowedException(beanName,                            "Singleton bean creation not allowed while singletons of this factory are in destruction " +                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");                }                if (logger.isDebugEnabled()) {                    logger.debug("Creating shared instance of singleton bean '" + beanName + "'");                }                //创建singleton bean之前,先检查inCreationCheckExclusions集合中不存在对应beanName,并将之放入当前正在创建的bean集合singletonsCurrentlyInCreation中                beforeSingletonCreation(beanName);                boolean newSingleton = false;                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);                if (recordSuppressedExceptions) {                    this.suppressedExceptions = new LinkedHashSet<Exception>();                }                try {                    //调用ObjectFactory的getObject方法,前面有提到,这个方法由匿名内部类定义过                    singletonObject = singletonFactory.getObject();                    newSingleton = true;                }                catch (IllegalStateException ex) {                    // Has the singleton object implicitly appeared in the meantime ->                    // if yes, proceed with it since the exception indicates that state.                    singletonObject = this.singletonObjects.get(beanName);                    if (singletonObject == null) {                        throw ex;                    }                }                catch (BeanCreationException ex) {                    if (recordSuppressedExceptions) {                        for (Exception suppressedException : this.suppressedExceptions) {                            ex.addRelatedCause(suppressedException);                        }                    }                    throw ex;                }                finally {                    if (recordSuppressedExceptions) {                        this.suppressedExceptions = null;                    }                    //无论是否完成singleton bean的创建,都要将之从singletonsCurrentlyInCreation移除                    afterSingletonCreation(beanName);                }                if (newSingleton) {                    //如果完成创建,将之添加到缓存中,具体实现看源码,有好几个缓存的添加和移除                    addSingleton(beanName, singletonObject);                }            }            return (singletonObject != NULL_OBJECT ? singletonObject : null);        }    }

以上代码核心的创建singleton bean的过程定义在AbstractAutowireCapableBeanFactory中,具体如下:

    @Override    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {        if (logger.isDebugEnabled()) {            logger.debug("Creating instance of bean '" + beanName + "'");        }        RootBeanDefinition mbdToUse = mbd;        //根据Beandefinition和beanName解析获取Class        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {            mbdToUse = new RootBeanDefinition(mbd);            mbdToUse.setBeanClass(resolvedClass);        }        // 标记和验证method的override属性,spring将配置中的lookup-method和replace-method在BeanDefinition中统一归类为override属性        try {            mbdToUse.prepareMethodOverrides();        }        catch (BeanDefinitionValidationException ex) {            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),                    beanName, "Validation of method overrides failed", ex);        }        try {            //给BeanPostProcessors一个机会使其能返回代理用于代替目标bean            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);            if (bean != null) {                return bean;            }        }        catch (Throwable ex) {            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,                    "BeanPostProcessor before instantiation of bean failed", ex);        }        Object beanInstance = doCreateBean(beanName, mbdToUse, args);        if (logger.isDebugEnabled()) {            logger.debug("Finished creating instance of bean '" + beanName + "'");        }        return beanInstance;    }

如果resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiationd方法直接返回了一个bean,那么将直接使用这个bean,否则进入doCreateBean方法:

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)            throws BeanCreationException {        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        if (instanceWrapper == null) {            //根据beanName,BeanDefinition和参数集创建实例,并封装为BeanWrapper,这个函数具体也就是先解析出Class(因为此时的BeanDefinition经过了处理,已不是最初的BeanDefinition),然后拿到Constructor,使用反射newInstance出具体的实例            instanceWrapper = createBeanInstance(beanName, mbd, args);        }        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);        mbd.resolvedTargetType = beanType;        // 允许后置处理器改变MergedBeanDefinition        synchronized (mbd.postProcessingLock) {            if (!mbd.postProcessed) {                try {                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                }                catch (Throwable ex) {                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,                            "Post-processing of merged bean definition failed", ex);                }                mbd.postProcessed = true;            }        }        // 是否提前曝光,条件是单例 + 允许循环依赖 + 单例在创建中,其中allowCircularReferences是可以设置的;注意,此处是解决循环依赖的关键,如果读者没忘记的话,前文中最初尝试从缓存中获取bean的时候,就会从一个singletonFactories获取ObjectFactory,这里定义一个匿名内部类,并将实例bean提前曝光,此时曝光的bean是没有任何属性值的        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&                isSingletonCurrentlyInCreation(beanName));        if (earlySingletonExposure) {            if (logger.isDebugEnabled()) {                logger.debug("Eagerly caching bean '" + beanName +                        "' to allow for resolving potential circular references");            }            addSingletonFactory(beanName, new ObjectFactory<Object>() {                @Override                public Object getObject() throws BeansException {                    return getEarlyBeanReference(beanName, mbd, bean);                }            });        }        // Initialize the bean instance.        Object exposedObject = bean;        try {            //填充bean的属性,这个函数会递归调用getSingleton的方法,也就是将我们前文分析的内容跑一遍,如果有循环依赖,那么在获取其属性时,就能获取到对应的bean            populateBean(beanName, mbd, instanceWrapper);            if (exposedObject != null) {                //初始化bean,其实说是初始化并不准确,这个方法主要做的事情是在进行一些接口方法的回调,如InitializingBean的afterPropertiesSet方法,BeanPostProcessor的postProcessAfterInitialization方法等                exposedObject = initializeBean(beanName, exposedObject, mbd);            }        }        catch (Throwable ex) {            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {                throw (BeanCreationException) ex;            }            else {                throw new BeanCreationException(                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);            }        }        if (earlySingletonExposure) {            Object earlySingletonReference = getSingleton(beanName, false);            if (earlySingletonReference != null) {                if (exposedObject == bean) {                    exposedObject = earlySingletonReference;                }                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {                    String[] dependentBeans = getDependentBeans(beanName);                    Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);                    for (String dependentBean : dependentBeans) {                        if (!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.");                    }                }            }        }        //注册DisposableBean,如果有destroy-method将作为销毁方法使用        try {            registerDisposableBeanIfNecessary(beanName, bean, mbd);        }        catch (BeanDefinitionValidationException ex) {            throw new BeanCreationException(                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);        }        return exposedObject;    }

这个方法返回的将是具有完整属性的bean,在前文我们提到过,真正给应用的bean需要经过getObjectForBeanInstance方法,这个方法来判断是返回当前的bean,还是FactoryBean,抑或是FactoryBean的getObect中获取的对象。


至此,spring从xml配置文件中获取bean的方法基本结束了,本文并没有非常详细的讲解每一个步骤,文中的注释也是作者自己的一些思考结合网络与书籍资料的结果,理解难免有偏差,如有问题,请联系wgy@live.cn!