实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1
本文以Xml Bean解析为例,步骤如下
Bean解析过程发生在AbstractApplicationContext#refresh()方法的第2步:obtainFreshBeanFactory()
/** * 初始化BeanFactory,在这一步完成了loadBeanDefinitions的加载 */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 抽象方法,交给子类实现。 // 子类刷新beanFactory,比如子类AbstractRefreshableApplicationContext会在refreshBeanFactory方法里createBeanFactory,并且执行loadBeanDefinitions加载资源配置。 // 而GenericApplicationContext只会对已经创建好的beanFactory实例设置一下id即可,loadBeanDefinitions放在了外部去做。 refreshBeanFactory(); // getBeanFactory也是抽象方法,由子类创建beanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
其中refreshBeanFactory()是个抽象方法,其子类AbstractRefreshableApplicationContext实现如下
/** * 刷新BeanFactory,实现父类AbstractApplicationContext的抽象方法 */ @Override protected final void refreshBeanFactory() throws BeansException { // 如果已经存在BeanFactory,销毁容器里的bean,关闭BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 创建beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 对IOC容器进行定制化,如设置启动参数、开启注解对自动装配等 customizeBeanFactory(beanFactory); // 调用载入bean定义对方法,loadBeanDefinitions(beanFactory)在本类是个抽象方法,交给子类实现 loadBeanDefinitions(beanFactory); // 加锁,写的时候不允许读写 synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
其中loadBeanDefinitions(beanFactory)是解析的入口,这里也是抽象方法,其子类AbstractXmlApplicationContext实现如下
/** * 实现AbstractRefreshableApplicationContext的抽象方法 */ @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. // 创建xml定义的bean读取器,容器使用它来读取bean配置资源 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. // 设置资源加载器 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); // 为bean读取器设置SAX xml解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. // 当bean读取器读取bean定义的xml资源文件时,启动xml的校验机制 initBeanDefinitionReader(beanDefinitionReader); // bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader); } /** * bean读取器真正实现加载的方法 */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { // 获取bean配置资源的定位,比如 ClassPathXmlApplicationContext(String[] paths, Class<?> clazz)使用类加载资源,会走到这里 Resource[] configResources = getConfigResources(); if (configResources != null) { // xml bean读取器调用其父类AbstractBeanDefinitionReader读取定位的bean配置资源 reader.loadBeanDefinitions(configResources); } // 获取bean配置资源的定位,比如 ClassPathXmlApplicationContext(String... configLocations)输入路径的构造,会走这里 String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
这里的AbstractBeanDefinitionReader将资源路径转换成了Resource对象,然后传给子类XmlBeanDefinitionReader来具体解析
@Override public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int counter = 0; for (String location : locations) { counter += loadBeanDefinitions(location); } return counter; } @Override public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); } public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException { // 获取在IOC容器初始化过程中设置的资源加载器 ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } if (resourceLoader instanceof ResourcePatternResolver) { // Resource pattern matching available. try { // 加载多个资源 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); // loadBeanDefinitions(resources)在本类没有实现,交给子类实现 int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException ex) { throw new BeanDefinitionStoreException( "Could not resolve bean definition resource pattern [" + location + "]", ex); } } else { // Can only load single resources by absolute URL. // 加载单个资源 Resource resource = resourceLoader.getResource(location); int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } }
XmlBeanDefinitionReader是具体的解析过程,在这里将Resource对象转成了Document对象,传给BeanDefinitionDocumentReader来解析注册
/** * 加载资源的入口方法 */ @Override public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { // 将读入的xml资源进行特殊编码处理 return loadBeanDefinitions(new EncodedResource(resource)); } /** * 加载xml形式的bean配置 */ public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { // 资源文件转为io流 InputStream inputStream = encodedResource.getResource().getInputStream(); try { // 从InputStream得到xml的解析源 InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } // 具体的读取流程 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } } /** * * 从xml文件加载资源,具体执行 */ protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // xml文件转化为DOM对象 Document doc = doLoadDocument(inputSource, resource); // 注册BeanDefinitions return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); } } /** * 将bean配置信息解析成容器内部数据结构 */ public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { // 获取一个解析器,这里用的是DefaultBeanDefinitionDocumentReader BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); // 获取已经注册的bean数量,getRegistry()获取的就是GenericApplicationContext int countBefore = getRegistry().getBeanDefinitionCount(); // 解析过程的入口,具体解析过程交给DefaultBeanDefinitionDocumentReader documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); // 返回本次解析数量 return getRegistry().getBeanDefinitionCount() - countBefore; }
DefaultBeanDefinitionDocumentReader是专门针对Document对象的解析器。会从根节点递归的解析,封装成beanDefinition注册到beanDefinitionMap里
/** * DefaultBeanDefinitionDocumentReader类 解析DOM资源 */ @Override public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); // 具体解析注册过程 doRegisterBeanDefinitions(root); } /** * * 从根节点递归解析 */ protected void doRegisterBeanDefinitions(Element root) { // 具体解析过程由BeanDefinitionParserDelegate实现,其内部定义了xml文件的各种元素 // 父级指向当前 BeanDefinitionParserDelegate parent = this.delegate; // 当前新建一个 this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } // 在解析之前,进行自定义解析,支持扩展 preProcessXml(root); // 从文档的根元素进行bean定义的解析 parseBeanDefinitions(root, this.delegate); // 在解析之后,进行自定义解析,支持扩展 postProcessXml(root); this.delegate = parent; } /** * 使用spring的bean规则从文档的根元素开始解析 */ 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)) { // 使用spring的bean规则解析元素节点 parseDefaultElement(ele, delegate); } else { // 使用用户自定义的bean规则解析元素节点 delegate.parseCustomElement(ele); } } } } else { // 使用用户自定义的bean规则解析元素节点 delegate.parseCustomElement(root); } } // 具体解析元素,并注册beanDefinition private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { // import导入元素解析 if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { importBeanDefinitionResource(ele); } // alias别名元素解析 else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { processAliasRegistration(ele); } // 普通bean元素解析 else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // 递归调用 doRegisterBeanDefinitions(ele); } } /** * * 封装成beanDefinition注册到beanDefinitionMap里 */ protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { // 会把解析出来的bean封装成BeanDefinitionHolder BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 在这一步把beanDefinition注册到了DefaultListableBeanFactory的beanDefinitionMap里 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)); } }
具体的注册过程由BeanDefinitionReaderUtils类实现
/** * BeanDefinitionReaderUtils类 注册过程 */ public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); // BeanDefinition的具体注册,这个registry是个注册器,DefaultListableBeanFactory就是注册器的一种实现 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); } } }
DefaultListableBeanFactory注册beanDefinition的具体逻辑,其实就是this.beanDefinitionMap.put(beanName, beanDefinition)
/** * DefaultListableBeanFactory类 注册beanDefinition实现 */ @Override 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 ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
总结:bean解析的代码相对来说比较多,各种调用关系链路比较长。总的来说就是父类先做抽象,把一些公共的逻辑实现,具体的解析细节交给子类来做。子类解析好后再调用注册器将BeanDefinition注册进去。