zoukankan      html  css  js  c++  java
  • Spring源码:Spring IoC容器加载过程(2)

     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     }
  • 相关阅读:
    UVA 1386 Cellular Automaton
    ZOJ 3331 Process the Tasks
    CodeForces 650B Image Preview
    CodeForces 650A Watchmen
    CodeForces 651B Beautiful Paintings
    CodeForces 651A Joysticks
    HUST 1601 Shepherd
    HUST 1602 Substring
    HUST 1600 Lucky Numbers
    POJ 3991 Seinfeld
  • 原文地址:https://www.cnblogs.com/burthughes/p/spring_2.html
Copyright © 2011-2022 走看看