1. 初始化

  • spring Ioc的初始化过程,大体是:读取xml资源,并解析,最终注册到Bean Factory中: image
  • 初始化过程:
    1
    2
    3
    4
    5
    6
    7
    8
    <bean id="xiaowang" class=com.springstudy.talentshow.SuperInstrumenttalist>
    <property name="instruments">
    <list>
    <ref bean="piano"/>
    <ref bean="saxophone"/>
    </list>
    </property>
    </bean>

加载时需要读取、解析、注册bean,这个过程具体的调用栈如下所示:
image

  • 代码详解:

    • 保存配置位置,并刷新: 在调用ClassPathXmlApplicationContext后,先会将配置位置信息保存到configLocations,供后面解析使用,之后,会调用AbstractApplicationContext的refresh方法进行刷新

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, 
      ApplicationContext parent) throws BeansException {
      super(parent);
      // 保存位置信息,比如`com/springstudy/talentshow/talent-show.xml`
      setConfigLocations(configLocations);
      if (refresh) {
      // 刷新
      refresh();
      }
      }
      public void refresh() throws BeansException, IllegalStateException {
      synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();
      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);
      try {
      // Allows post-processing of the bean factory in context subclasses.
      postProcessBeanFactory(beanFactory);
      // Invoke factory processors registered as beans in the context.
      invokeBeanFactoryPostProcessors(beanFactory);
      // Register bean processors that intercept bean creation.
      registerBeanPostProcessors(beanFactory);
      // Initialize message source for this context.
      initMessageSource();
      // Initialize event multicaster for this context.
      initApplicationEventMulticaster();
      // Initialize other special beans in specific context subclasses.
      onRefresh();
      // Check for listener beans and register them.
      registerListeners();
      // Instantiate all remaining (non-lazy-init) singletons.
      finishBeanFactoryInitialization(beanFactory);
      // Last step: publish corresponding event.
      finishRefresh();
      }
      catch (BeansException ex) {
      // Destroy already created singletons to avoid dangling resources.
      destroyBeans();
      // Reset 'active' flag.
      cancelRefresh(ex);
      // Propagate exception to caller.
      throw ex;
      }
      }
      }
    • 创建载入BeanFactory

      1
      2
      3
      4
      5
      6
      7
      protected final void refreshBeanFactory() throws BeansException {
      // ... ...
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      // ... ...
      loadBeanDefinitions(beanFactory);
      // ... ...
      }
    • 创建XMLBeanDefinitionReader

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
      throws BeansException, IOException {
      // Create a new XmlBeanDefinitionReader for the given BeanFactory.
      XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
      // ... ...
      // Allow a subclass to provide custom initialization of the reader,
      // then proceed with actually loading the bean definitions.
      initBeanDefinitionReader(beanDefinitionReader);
      loadBeanDefinitions(beanDefinitionReader);
      }
  • 读取

    • 创建处理每一个resource

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      public int loadBeanDefinitions(String location, Set<Resource> actualResources)
      throws BeanDefinitionStoreException {
      // ... ...
      // 通过Location来读取Resource
      Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
      int loadCount = loadBeanDefinitions(resources);
      // ... ...
      }
      public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
      Assert.notNull(resources, "Resource array must not be null");
      int counter = 0;
      for (Resource resource : resources) {
      // 载入每一个resource
      counter += loadBeanDefinitions(resource);
      }
      return counter;
      }
    • 处理XML每个元素

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
      // ... ...
      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)) {
      // 处理每个xml中的元素,可能是import、alias、bean
      parseDefaultElement(ele, delegate);
      }
      else {
      delegate.parseCustomElement(ele);
      }
      }
      }
      // ... ...
      }
    • 解析注册Bean

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
      // 解析
      BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
      if (bdHolder != null) {
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
      // 注册
      // Register the final decorated instance.
      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));
      }
      }
  • 解析
    image

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 处理每个Bean的元素
    public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, BeanDefinition containingBean) {
    // ... ...
    // 创建beandefinition
    AbstractBeanDefinition bd = createBeanDefinition(className, parent);
    parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
    bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
    parseMetaElements(ele, bd);
    parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
    parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
    // 处理“Constructor”
    parseConstructorArgElements(ele, bd);
    // 处理“Preperty”
    parsePropertyElements(ele, bd);
    parseQualifierElements(ele, bd);
    // ... ...
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 处理属性值
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
String elementName = (propertyName != null) ?
"<property> element for property '" + propertyName + "'" :
"<constructor-arg> element";
// ... ...
if (hasRefAttribute) {
// 处理引用
String refName = ele.getAttribute(REF_ATTRIBUTE);
if (!StringUtils.hasText(refName)) {
error(elementName + " contains empty 'ref' attribute", ele);
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(extractSource(ele));
return ref;
}
else if (hasValueAttribute) {
// 处理值
TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
valueHolder.setSource(extractSource(ele));
return valueHolder;
}
else if (subElement != null) {
// 处理子类型(比如list、map等)
return parsePropertySubElement(subElement, bd);
}
// ... ...
}
  • 注册
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {
    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
    for (String alias : aliases) {
    registry.registerAlias(beanName, alias);
    }
    }
    }
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {
    // ......
    // 将beanDefinition注册
    this.beanDefinitionMap.put(beanName, beanDefinition);
    // ......
    }

2.注入依赖

  • 当完成初始化IOC容器后,如果bean没有设置lazy-init(延迟加载)属性,那么bean的实例就会在初始化IOC完成之后,及时地进行初始化。初始化时会先建立实例,然后根据配置利用反射对实例进行进一步操作,具体流程如下所示
    image
  • 创建bean实例
  • image
  • 创建Bean和注入Bean的属性时,都在doCreateBean函数中:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
    final Object[] args) {
    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
    // 创建bean的实例
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // ... ...
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    // 初始化bean的实例,如注入属性
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    }
    // ... ...
    }

转载:Spring Ioc核心源码学习