1. 程式人生 > >Spring 源碼解析(五)解析<bean></bean>

Spring 源碼解析(五)解析<bean></bean>

ret nes context source syn protect exc spa 這一

這一章我們來分析Spring是如何解析<bena></bean>生成BeanDefinition的,進入

 //org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
1
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { 2 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { 3 importBeanDefinitionResource(ele);//<import/>
4 } 5 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { 6 processAliasRegistration(ele);//<alias/> 7 } 8 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { 9 processBeanDefinition(ele, delegate);//<bean/> 10 } 11 else
if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { 12 // recurse 13 doRegisterBeanDefinitions(ele);//嵌套的<beans/> 14 } 15 }

第9行,解析<bean/>節點,進入processBeanDefinition方法

 //org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
1
/**
2 * Process the given bean element, parsing the bean definition 3 * and registering it with the registry. 4 */ 5 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { 6 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); 7 if (bdHolder != null) { 8 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); 9 try { 10 // Register the final decorated instance. 11 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); 12 } 13 catch (BeanDefinitionStoreException ex) { 14 getReaderContext().error("Failed to register bean definition with name ‘" + 15 bdHolder.getBeanName() + "‘", ele, ex); 16 } 17 // Send registration event. 18 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); 19 } 20 }

第6行,創建了BeanDefinitionHolder實例(此實例包含了BeanDefinition、BeanName、Bean的別名)
第11行,註冊BeanDefinition,其中getReaderContext()得到是在XmlBeanDefinitionReader通過createReaderContext方法創建的XmlReaderContext實例。getReaderContext().getRegistry()調用是XmlBeanDefinitionReader實例的getRegistry(),得到是BeanDefinitionRegistry實例(實現類DefaultListableBeanFactory)

//org.springframework.beans.factory.xml.XmlBeanDefinitionReader
1
/** 2 * Create the {@link XmlReaderContext} to pass over to the document reader. 3 */ 4 public XmlReaderContext createReaderContext(Resource resource) { 5 return new XmlReaderContext(resource, this.problemReporter, this.eventListener, 6 this.sourceExtractor, this, getNamespaceHandlerResolver()); 7 }

進入registerBeanDefinition方法

 //org.springframework.beans.factory.support.BeanDefinitionReaderUtils
1
/** 2 * Register the given bean definition with the given bean factory. 3 * @param definitionHolder the bean definition including name and aliases 4 * @param registry the bean factory to register with 5 * @throws BeanDefinitionStoreException if registration failed 6 */ 7 public static void registerBeanDefinition( 8 BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) 9 throws BeanDefinitionStoreException { 10 11 // Register bean definition under primary name. 12 String beanName = definitionHolder.getBeanName(); 13 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); 14 15 // Register aliases for bean name, if any. 16 String[] aliases = definitionHolder.getAliases(); 17 if (aliases != null) { 18 for (String aliase : aliases) { 19 registry.registerAlias(beanName, aliase); 20 } 21 } 22 }

第12行,獲取beanName

第13行,調用BeanDefinitionRegistry(實現類是DefaultListableBeanFactory)的registerBeanDefinition方法註冊BeanDefinition,進入方法

 //org.springframework.beans.factory.support.DefaultListableBeanFactory
1
//--------------------------------------------------------------------- 2 // Implementation of BeanDefinitionRegistry interface 3 //--------------------------------------------------------------------- 4 5 @Override 6 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 7 throws BeanDefinitionStoreException { 8 9 Assert.hasText(beanName, "Bean name must not be empty"); 10 Assert.notNull(beanDefinition, "BeanDefinition must not be null"); 11 12 if (beanDefinition instanceof AbstractBeanDefinition) { 13 try { 14 ((AbstractBeanDefinition) beanDefinition).validate(); 15 } 16 catch (BeanDefinitionValidationException ex) { 17 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 18 "Validation of bean definition failed", ex); 19 } 20 } 21 22 synchronized (this.beanDefinitionMap) { 23 BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName); 24 if (oldBeanDefinition != null) { 25 if (!this.allowBeanDefinitionOverriding) { 26 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 27 "Cannot register bean definition [" + beanDefinition + "] for bean ‘" + beanName + 28 "‘: There is already [" + oldBeanDefinition + "] bound."); 29 } 30 else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { 31 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE 32 if (this.logger.isWarnEnabled()) { 33 this.logger.warn("Overriding user-defined bean definition for bean ‘" + beanName + 34 " with a framework-generated bean definition ‘: replacing [" + 35 oldBeanDefinition + "] with [" + beanDefinition + "]"); 36 } 37 } 38 else { 39 if (this.logger.isInfoEnabled()) { 40 this.logger.info("Overriding bean definition for bean ‘" + beanName + 41 "‘: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); 42 } 43 } 44 } 45 else { 46 this.beanDefinitionNames.add(beanName); 47 this.frozenBeanDefinitionNames = null; 48 } 49 this.beanDefinitionMap.put(beanName, beanDefinition); 50 } 51 52 resetBeanDefinition(beanName); 53 }

第46行,把beanName加入beanDefinitionNames(List<String>類型)

第49行,把beanName、beanDefinition按照Key-Value鍵值對放入beanDefinitionMap(Map<String, BeanDefinition>類型)

通過上面分析,我們已經可以得到所有的beanName和beanDefinition,那麽什麽時候創建bean的實例呢,下一章再進行介紹。

Spring 源碼解析(五)解析<bean></bean>