• spring启动过程之源码跟踪(上)spring Debug


    1,初始化容器

    1 ClassPathXmlApplicationContext context=new
    2                 ClassPathXmlApplicationContext("/applicationContext.xml");

       步骤1:构造方法如下:

    1 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
    2             throws BeansException {
    3         super(parent);
    4         setConfigLocations(configLocations);
    5         if (refresh) {
    6             refresh();
    7         }
    8     }

     步骤2:重头戏到了!

     1     public void refresh() throws BeansException, IllegalStateException {
     2         synchronized (this.startupShutdownMonitor) {
     3             // Prepare this context for refreshing.
     4             prepareRefresh();
     5 
     6             // Tell the subclass to refresh the internal bean factory.
     7             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
     8 
     9             // Prepare the bean factory for use in this context.
    10             prepareBeanFactory(beanFactory);
    11 
    12             try {
    13                 // Allows post-processing of the bean factory in context subclasses.
    14                 postProcessBeanFactory(beanFactory);
    15 
    16                 // Invoke factory processors registered as beans in the context.
    17                 invokeBeanFactoryPostProcessors(beanFactory);
    18 
    19                 // Register bean processors that intercept bean creation.
    20                 registerBeanPostProcessors(beanFactory);
    21 
    22                 // Initialize message source for this context.
    23                 initMessageSource();
    24 
    25                 // Initialize event multicaster for this context.
    26                 initApplicationEventMulticaster();
    27 
    28                 // Initialize other special beans in specific context subclasses.
    29                 onRefresh();
    30 
    31                 // Check for listener beans and register them.
    32                 registerListeners();
    33 
    34                 // Instantiate all remaining (non-lazy-init) singletons.
    35                 finishBeanFactoryInitialization(beanFactory);
    36 
    37                 // Last step: publish corresponding event.
    38                 finishRefresh();
    39             }
    40 
    41             catch (BeansException ex) {
    42                 // Destroy already created singletons to avoid dangling resources.
    43                 beanFactory.destroySingletons();
    44 
    45                 // Reset 'active' flag.
    46                 cancelRefresh(ex);
    47 
    48                 // Propagate exception to caller.
    49                 throw ex;
    50             }
    51         }
    52     }

     步骤3:获取beanFactory

     1     protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
     2         refreshBeanFactory();
     3         ConfigurableListableBeanFactory beanFactory = getBeanFactory();
     4 
     5         if (logger.isInfoEnabled()) {
     6             logger.info("Bean factory for application context [" + getId() + "]: " +
     7                     ObjectUtils.identityToString(beanFactory));
     8         }
     9         if (logger.isDebugEnabled()) {
    10             logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in " + this);
    11         }
    12 
    13         return beanFactory;
    14     }

    步骤3-1

     1     protected final void refreshBeanFactory() throws BeansException {
     2         if (hasBeanFactory()) {
     3             destroyBeans();
     4             closeBeanFactory();
     5         }
     6         try {
     7             DefaultListableBeanFactory beanFactory = createBeanFactory();
     8             customizeBeanFactory(beanFactory);
     9             loadBeanDefinitions(beanFactory);
    10             synchronized (this.beanFactoryMonitor) {
    11                 this.beanFactory = beanFactory;
    12             }
    13         }
    14         catch (IOException ex) {
    15             throw new ApplicationContextException(
    16                     "I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);
    17         }
    18     }

    步骤3-2 加载beans的定义(AbstractXmlApplicationContext.java)

     1     /**
     2      * Loads the bean definitions via an XmlBeanDefinitionReader.
     3      * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     4      * @see #initBeanDefinitionReader
     5      * @see #loadBeanDefinitions
     6      */
     7     protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
     8         // Create a new XmlBeanDefinitionReader for the given BeanFactory.
     9         XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    10 
    11         // Configure the bean definition reader with this context's
    12         // resource loading environment.
    13         beanDefinitionReader.setResourceLoader(this);
    14         beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    15 
    16         // Allow a subclass to provide custom initialization of the reader,
    17         // then proceed with actually loading the bean definitions.
    18         initBeanDefinitionReader(beanDefinitionReader);
    19         loadBeanDefinitions(beanDefinitionReader);
    20     }

    步骤3-3

     1 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
     2         Resource[] configResources = getConfigResources();
     3         if (configResources != null) {
     4             reader.loadBeanDefinitions(configResources);
     5         }
     6         String[] configLocations = getConfigLocations();
     7         if (configLocations != null) {
     8             reader.loadBeanDefinitions(configLocations);
     9         }
    10     }

    步骤3-4 XmlBeanDefinitionReader.java

     1     public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
     2         Assert.notNull(encodedResource, "EncodedResource must not be null");
     3         if (logger.isInfoEnabled()) {
     4             logger.info("Loading XML bean definitions from " + encodedResource.getResource());
     5         }
     6 
     7         Set currentResources = (Set) this.resourcesCurrentlyBeingLoaded.get();
     8         if (currentResources == null) {
     9             currentResources = new HashSet(4);
    10             this.resourcesCurrentlyBeingLoaded.set(currentResources);
    11         }
    12         if (!currentResources.add(encodedResource)) {
    13             throw new BeanDefinitionStoreException(
    14                     "Detected recursive loading of " + encodedResource + " - check your import definitions!");
    15         }
    16         try {
    17             InputStream inputStream = encodedResource.getResource().getInputStream();
    18             try {
    19                 InputSource inputSource = new InputSource(inputStream);
    20                 if (encodedResource.getEncoding() != null) {
    21                     inputSource.setEncoding(encodedResource.getEncoding());
    22                 }
    23                 return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    24             }
    25             finally {
    26                 inputStream.close();
    27             }
    28         }
    29         catch (IOException ex) {
    30             throw new BeanDefinitionStoreException(
    31                     "IOException parsing XML document from " + encodedResource.getResource(), ex);
    32         }
    33         finally {
    34             currentResources.remove(encodedResource);
    35             if (currentResources.isEmpty()) {
    36                 this.resourcesCurrentlyBeingLoaded.set(null);
    37             }
    38         }
    39     }

    步骤3-5 读取xml文件
    DefaultBeanDefinitionDocumentReader.java

     1     /**
     2      * Parses bean definitions according to the "spring-beans" DTD.
     3      * <p>Opens a DOM Document; then initializes the default settings
     4      * specified at <code>&lt;beans&gt;</code> level; then parses
     5      * the contained bean definitions.
     6      */
     7     public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
     8         this.readerContext = readerContext;
     9 
    10         logger.debug("Loading bean definitions");
    11         Element root = doc.getDocumentElement();
    12 
    13         BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
    14 
    15         preProcessXml(root);
    16         parseBeanDefinitions(root, delegate);
    17         postProcessXml(root);
    18     }

     (以下图片为网上所得,非原创,谢谢原作者)

    创建 BeanFactory 时序图

    解析和登记 Bean 对象时序图

  • 相关阅读:
    BZOJ 1008 [HNOI2008]越狱
    BZOJ 1588 [HNOI2002]营业额统计
    20170520 DP阶段总结
    HDU 3507 Print Article
    浅谈随机数生成器及其应用
    BZOJ 1010 [HNOI2008]toy 玩具装箱
    斯堪福三定律
    这是我在博客园上的第一篇博客
    微博粉丝服务---“公众号”开发
    XML解析---利用XStream解析xml数据及反构造Java对象
  • 原文地址:https://www.cnblogs.com/davidwang456/p/2954563.html
Copyright © 2020-2023  润新知