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

在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!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值