Spring源码:Spring IoC容器加载过程(2)
2019-05-13 07:15:00来源:博客园 阅读 ()
Spring源码版本:4.3.23.RELEASE
一、加载XML配置
通过XML配置创建Spring,创建入口是使用org.springframework.context.support.ClassPathXmlApplicationContext类,创建容器的代码如下:
1 package hello; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class HelloWorld 7 { 8 public static void main(String[] args) { 9 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 10 System.out.println(context.getBean("hello.Dog", Dog.class).name); 11 System.out.println(context.getBean("hello.Dog#0", Dog.class).name); 12 } 13 } 14 15 class Dog { 16 String name = "PiPi"; 17 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 5 6 <bean class="hello.Dog"/> 7 8 </beans>
1.1 如果bean没有配置id或name属性,那Spring会取class属性值(也就是全限定类名)加#index(index为bean对象在容器里的序号)作为name,取类全限定名作为别名aliases。具体看下面源码:
org/springframework/beans/factory/xml/BeanDefinitionParserDelegate.java#parseBeanDefinitionElement
1 /** 2 * Parses the supplied {@code <bean>} element. May return {@code null} 3 * if there were errors during parse. Errors are reported to the 4 * {@link org.springframework.beans.factory.parsing.ProblemReporter}. 5 */ 6 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { 7 String id = ele.getAttribute(ID_ATTRIBUTE); 8 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); 9 10 List<String> aliases = new ArrayList<String>(); 11 if (StringUtils.hasLength(nameAttr)) { 12 String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); 13 aliases.addAll(Arrays.asList(nameArr)); 14 } 15 16 String beanName = id; 17 if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { 18 beanName = aliases.remove(0); 19 if (logger.isDebugEnabled()) { 20 logger.debug("No XML 'id' specified - using '" + beanName + 21 "' as bean name and " + aliases + " as aliases"); 22 } 23 } 24 25 if (containingBean == null) { 26 checkNameUniqueness(beanName, aliases, ele); 27 } 28 29 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); 30 if (beanDefinition != null) { 31 if (!StringUtils.hasText(beanName)) { 32 try { 33 if (containingBean != null) { 34 beanName = BeanDefinitionReaderUtils.generateBeanName( 35 beanDefinition, this.readerContext.getRegistry(), true); 36 } 37 else { 38 beanName = this.readerContext.generateBeanName(beanDefinition); //获取到的bean名称为com.example.Hello#0这样的格式,#后面的数字为该类对象在进程中的编号。 39 // Register an alias for the plain bean class name, if still possible, 40 // if the generator returned the class name plus a suffix. 41 // This is expected for Spring 1.2/2.0 backwards compatibility. 42 String beanClassName = beanDefinition.getBeanClassName(); //获取class属性配置的bean的类名(全限定类名) 43 if (beanClassName != null && 44 beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && 45 !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { 46 aliases.add(beanClassName); //使用全限定类名作为别名 47 } 48 } 49 if (logger.isDebugEnabled()) { 50 logger.debug("Neither XML 'id' nor 'name' specified - " + 51 "using generated bean name [" + beanName + "]"); 52 } 53 } 54 catch (Exception ex) { 55 error(ex.getMessage(), ele); 56 return null; 57 } 58 } 59 String[] aliasesArray = StringUtils.toStringArray(aliases); 60 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); //创建bean定义对象 61 } 62 63 return null; 64 }
1.2 Bean的定义加载到一个ConcurrentHashMap,key为bean名称,value为org.springframework.beans.factory.config.BeanDefinition:
org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap
/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
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 BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); 23 if (existingDefinition != null) { 24 if (!isAllowBeanDefinitionOverriding()) { 25 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, 26 "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + 27 "': There is already [" + existingDefinition + "] bound."); 28 } 29 else if (existingDefinition.getRole() < beanDefinition.getRole()) { 30 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE 31 if (logger.isWarnEnabled()) { 32 logger.warn("Overriding user-defined bean definition for bean '" + beanName + 33 "' with a framework-generated bean definition: replacing [" + 34 existingDefinition + "] with [" + beanDefinition + "]"); 35 } 36 } 37 else if (!beanDefinition.equals(existingDefinition)) { 38 if (logger.isInfoEnabled()) { 39 logger.info("Overriding bean definition for bean '" + beanName + 40 "' with a different definition: replacing [" + existingDefinition + 41 "] with [" + beanDefinition + "]"); 42 } 43 } 44 else { 45 if (logger.isDebugEnabled()) { 46 logger.debug("Overriding bean definition for bean '" + beanName + 47 "' with an equivalent definition: replacing [" + existingDefinition + 48 "] with [" + beanDefinition + "]"); 49 } 50 } 51 this.beanDefinitionMap.put(beanName, beanDefinition); 52 } 53 else { 54 if (hasBeanCreationStarted()) { 55 // Cannot modify startup-time collection elements anymore (for stable iteration) 56 synchronized (this.beanDefinitionMap) { 57 this.beanDefinitionMap.put(beanName, beanDefinition); 58 List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); 59 updatedDefinitions.addAll(this.beanDefinitionNames); 60 updatedDefinitions.add(beanName); 61 this.beanDefinitionNames = updatedDefinitions; 62 if (this.manualSingletonNames.contains(beanName)) { 63 Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); 64 updatedSingletons.remove(beanName); 65 this.manualSingletonNames = updatedSingletons; 66 } 67 } 68 } 69 else { 70 // Still in startup registration phase 71 this.beanDefinitionMap.put(beanName, beanDefinition); 72 this.beanDefinitionNames.add(beanName); 73 this.manualSingletonNames.remove(beanName); 74 } 75 this.frozenBeanDefinitionNames = null; 76 } 77 78 if (existingDefinition != null || containsSingleton(beanName)) { 79 resetBeanDefinition(beanName); 80 } 81 }
原文链接:https://www.cnblogs.com/burthughes/p/spring_2.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Hive教程(1)
下一篇:Problem09 求完数
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash