入口:ClassPathXmlApplicationContext类
关键方法:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if(refresh) { //刷新容器 this.refresh(); } }
public ClassPathXmlApplicationContext(String[] paths, Class clazz, ApplicationContext parent) throws BeansException { super(parent); Assert.notNull(paths, "Path array must not be null"); Assert.notNull(clazz, "Class argument must not be null"); this.configResources = new Resource[paths.length]; for(int i = 0; i < paths.length; ++i) { this.configResources[i] = new ClassPathResource(paths[i], clazz); } //刷新容器 this.refresh(); }
关键点:this.refresh();这个调用就是用来销毁和创建容器的
跳转到AbstractApplicationContext类
方法:
public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); //定制化BeanFactory ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var5) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5); this.destroyBeans(); this.cancelRefresh(var5); throw var5; } } }
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();此处就是去销毁容器以及重新创建定制化容器的核心
跳转到AbstractApplicationContext类
方法:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //刷新BeanFactory this.refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = this.getBeanFactory(); if(this.logger.isDebugEnabled()) { this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory); } return beanFactory; }
然后跳转到AbstractRefreshableApplicationContext类
方法:
protected final void refreshBeanFactory() throws BeansException { //此处判断容器是否存在,并进行容器的销毁和关闭 if(this.hasBeanFactory()) { this.destroyBeans(); this.closeBeanFactory(); } try { //创建BeanFactory DefaultListableBeanFactory beanFactory = this.createBeanFactory(); beanFactory.setSerializationId(this.getId()); //定制BeanFactory this.customizeBeanFactory(beanFactory); //加载BeanDefinition this.loadBeanDefinitions(beanFactory); Object var2 = this.beanFactoryMonitor; synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
此处开始进入spring容器的定位,加载注册3大步骤的第一步
this.loadBeanDefinitions(beanFactory);由此处代码继续跟踪下去
跳转到AbstractXmlApplicationContext类
方法:
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //new 一个Reader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); this.initBeanDefinitionReader(beanDefinitionReader);、 //使用新定义的reader去加载BeanDefinition this.loadBeanDefinitions(beanDefinitionReader); }
然后跳转到AbstractXmlApplicationContext类
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = this.getConfigResources(); if(configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = this.getConfigLocations(); if(configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
再继续往下进入AbstractBeanDefinitionReader类
方法:
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; Resource[] arr$ = resources; int len$ = resources.length; for(int i$ = 0; i$ < len$; ++i$) { Resource resource = arr$[i$]; counter += this.loadBeanDefinitions((Resource)resource); } return counter; }
counter += this.loadBeanDefinitions((Resource)resource);此处有2个实现类:一个是PropertiesBeanDefinitionReader一个是XmlBeanDefinitionReader分别用来处理Properties和XML的实现类
下面我们进入XmlBeanDefinitionReader
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return this.loadBeanDefinitions(new EncodedResource(resource)); } public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if(this.logger.isInfoEnabled()) { this.logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get(); if(currentResources == null) { currentResources = new HashSet(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if(!((Set)currentResources).add(encodedResource)) { throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } else { int var5; try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if(encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //此处就是spring真正去做加载BeanDefinition的实现逻辑(真正干活的方法出现了!) var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException var15) { throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15); } finally { ((Set)currentResources).remove(encodedResource); if(((Set)currentResources).isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } return var5; } }
继续往下:
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { int validationMode = this.getValidationModeForResource(resource); //初始化Document后续用来处理xml的各层属性 Document doc = this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, validationMode, this.isNamespaceAware()); //注册BeanDefinition return this.registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException var5) { throw var5; } catch (SAXParseException var6) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6); } catch (SAXException var7) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7); } catch (ParserConfigurationException var8) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8); } catch (IOException var9) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9); } catch (Throwable var10) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10); } }
继续:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader(); documentReader.setEnvironment(this.getEnvironment()); int countBefore = this.getRegistry().getBeanDefinitionCount(); //此处去注册BeanDefinition documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource)); return this.getRegistry().getBeanDefinitionCount() - countBefore; }
继续:
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; this.logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); //此处去进行注册BeanDefinition实际操作 this.doRegisterBeanDefinitions(root); }
protected void doRegisterBeanDefinitions(Element root) { String profileSpec = root.getAttribute("profile"); if(StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; "); if(!this.getEnvironment().acceptsProfiles(specifiedProfiles)) { return; } } //获取委派类(设计模式的一种) BeanDefinitionParserDelegate parent = this.delegate; this.delegate = this.createDelegate(this.readerContext, root, parent); this.preProcessXml(root); //加载XML并处理XML的相关逻辑 this.parseBeanDefinitions(root, this.delegate); this.postProcessXml(root); this.delegate = parent; }
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if(delegate.isDefaultNamespace(root)) { 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)) { this.parseDefaultElement(ele, delegate); } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
节点属性的处理
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if(delegate.nodeNameEquals(ele, "import")) {//import节点 this.importBeanDefinitionResource(ele); } else if(delegate.nodeNameEquals(ele, "alias")) {//alias节点 this.processAliasRegistration(ele); } else if(delegate.nodeNameEquals(ele, "bean")) {//bean节点 this.processBeanDefinition(ele, delegate); } else if(delegate.nodeNameEquals(ele, "beans")) {//beans节点 this.doRegisterBeanDefinitions(ele); } }
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if(bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { //注册bean BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException var5) { this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5); } this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } }
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { //获取beanName String beanName = definitionHolder.getBeanName(); //注册BeanDefinition registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if(aliases != null) { String[] arr$ = aliases; int len$ = aliases.length; for(int i$ = 0; i$ < len$; ++i$) { String aliase = arr$[i$]; registry.registerAlias(beanName, aliase); } } }
这是跳转到DefaultListableBeanFactory类
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(64);
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if(beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var7) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var7); } } Map var4 = this.beanDefinitionMap; BeanDefinition oldBeanDefinition; synchronized(this.beanDefinitionMap) { oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if(oldBeanDefinition != null) { if(!this.allowBeanDefinitionOverriding) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } if(this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { this.beanDefinitionNames.add(beanName); this.frozenBeanDefinitionNames = null; } //将beanDefinition放入beanDefinitionMap中,并以beanName作为key,此处是一个线程安全的beanDefinitionMap this.beanDefinitionMap.put(beanName, beanDefinition); } if(oldBeanDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }
到此已经将xml文件中的相关属性加载到了beanDefinitionMap这个容器中