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><beans></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 }
(以下图片为网上所得,非原创,谢谢原作者)
微信公众号: 架构师日常笔记 欢迎关注!