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

来源:互联网 发布:php datetime 时区 编辑:程序博客网 时间:2024/06/07 23:38

1,初始化容器

1 ClassPathXmlApplicationContext context=new2                 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's12         // 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 对象时序图

 

原创粉丝点击