spring源码解析-从xml配置文件中获取bean
2017-10-10 21:04
751 查看
在spring的实际应用中,我们经常将bean定义在xml的配置文件当中,那么,spring是如何从xml加载bean的呢?今天我们将从源码的层面进行简单的解读。假设,我们有如下一个spring的配置文件,这是我从一个dubbo的demo中获取的。
在spring 3.1的版本之前,我们可以使用
构造函数中xml配置文件作为Resource载入。
在spring 3.1之后的版本,建议使用
从代码看,加载的核心代码是在第三行和第四行,我们进入到loadBeanDefinitions方法看它的源码,里面加入了一些我自己的注解:
我们再仔细看一下doLoadBeanDefinitions的源码:
我们这次看一下解析默认element的parseDefaultElement方法:
此处,我们主要看一下加载bean的方法:
在解读
接下来,我们看看
从注释中看到,我们创建对象的过程是在getSingleton(String beanName, ObjectFactory
以上代码核心的创建singleton bean的过程定义在
如果resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiationd方法直接返回了一个bean,那么将直接使用这个bean,否则进入doCreateBean方法:
这个方法返回的将是具有完整属性的bean,在前文我们提到过,真正给应用的bean需要经过getObjectForBeanInstance方法,这个方法来判断是返回当前的bean,还是FactoryBean,抑或是FactoryBean的getObect中获取的对象。
至此,spring从xml配置文件中获取bean的方法基本结束了,本文并没有非常详细的讲解每一个步骤,文中的注释也是作者自己的一些思考结合网络与书籍资料的结果,理解难免有偏差,如有问题,请联系wgy@live.cn!
<?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之后的版本,建议使用
DefaultListableBeanFactory和
XmlBeanDefinitionReader来从xml中加载bean。
DefaultListableBeanFactory是
ListableBeanFactory接口和
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!
相关文章推荐
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
- Spring源码分析2 — XML配置文件的解析流程
- Spring源码学习--Spring配置解析文件ApplicationContext.xml(一)
- Spring源码浅析 -- XML配置文件的载入与解析
- 从applicationContext.xml到beanfactiory 谈Spring从配置文件中获取bean
- spring中读取xml配置文件、获取bean的几种方式
- spring中读取xml配置文件、获取bean的几种方式
- spring中读取xml配置文件、获取bean的几种方式
- Spring3.2 中 Bean 定义之基于 XML 配置方式的源码解析
- spring中读取xml配置文件、获取bean的几种方式
- 通过DefaultListableBeanFactory加载.xml配置文件学习Spring-IoC容器注册/加载bean的机制(源码走读)
- web.xml中配置spring的几种方式 以及 Spring获取Bean的几种方式
- Spring如何通过application.xml解析出bean的配置信息
- SQL文的管理和解析(一)利用Spring的Resource管理SQL的XML配置文件
- spring源码解读-加载解析配置文件
- web.xml中配置spring的几种方式 以及 Spring获取Bean的几种方式
- spring利用扫描方式对bean的处理(对任何版本如何获取xml配置信息的处理)
- Spring源码分析-配置文件的解析(二)