参考源
《Spring源码深度解析(第2版)》
版本
本文章基于 Spring 5.3.15
Spring IOC 的核心是
其中一共有 13 个主要方法,这里分析第 2 个:AbstractApplicationContext
的refresh
方法。obtainFreshBeanFactory
。
1 AbstractApplicationContext
1-1 创建容器对象
obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 初始化 BeanFactory,并进行 XML 文件读取,将得到的 BeanFactory 记录在当前实体的属性中 refreshBeanFactory(); // 返回当前实体的 beanFactory 属性 return getBeanFactory();}
1-2 初始化 BeanFactory
refreshBeanFactory()
2 AbstractRefreshableApplicationContext
protected final void refreshBeanFactory() throws BeansException { // 如果存在 beanFactory if (hasBeanFactory()) { // 销毁 Bean destroyBeans(); // 关闭 Bean 工厂 closeBeanFactory(); } try { // 创建内部的 Bean 工厂 DefaultListableBeanFactory beanFactory = createBeanFactory(); // 指定序列化 ID,可以从 ID 反序列化到 BeanFactory 对象 beanFactory.setSerializationId(getId()); // 定制 BeanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖 customizeBeanFactory(beanFactory); // 加载 Bean 定义信息,初始化 documentReader,并进行 XML 文件读取及解析 loadBeanDefinitions(beanFactory); // 使用全局变量记录 BeanFactory 类实例 this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); }}
2-1 创建内部的 Bean 工厂
createBeanFactory()
protected DefaultListableBeanFactory createBeanFactory() { // 获取内部父Bean工厂 return new DefaultListableBeanFactory(getInternalParentBeanFactory());}
2-2 获取内部父Bean工厂
getInternalParentBeanFactory()
1 AbstractApplicationContext
protected BeanFactory getInternalParentBeanFactory() { return (getParent() instanceof ConfigurableApplicationContext ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent());}
1-2 获取父类
getParent()
public ApplicationContext getParent() { return this.parent;}
1-2 获取 Bean 工厂
getBeanFactory()
public final ConfigurableListableBeanFactory getBeanFactory() { DefaultListableBeanFactory beanFactory = this.beanFactory; if (beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return beanFactory;}
if (beanFactory == null)
由于前面已经获取了 Bean 工厂,这里直接返回。
2 AbstractRefreshableApplicationContext
2-1 构建默认的可排列 Bean 工厂对象
new DefaultListableBeanFactory(getInternalParentBeanFactory())
3 DefaultListableBeanFactory
public DefaultListableBeanFactory(@Nullable BeanFactory parentBeanFactory) { super(parentBeanFactory);}
4 AbstractAutowireCapableBeanFactory
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) { this(); // 设置父类 Bean 工厂 setParentBeanFactory(parentBeanFactory);}
4-1 构造方法
this()
public AbstractAutowireCapableBeanFactory() { super(); // 忽略要依赖的接口 ignoreDependencyInterface(BeanNameAware.class); ignoreDependencyInterface(BeanFactoryAware.class); ignoreDependencyInterface(BeanClassLoaderAware.class); if (NativeDetector.inNativeImage()) { this.instantiationStrategy = new SimpleInstantiationStrategy(); } else { this.instantiationStrategy = new CglibSubclassingInstantiationStrategy(); }}
4-2 父类构造方法
super()
5 AbstractBeanFactory
public AbstractBeanFactory() { }
4 AbstractAutowireCapableBeanFactory
4-2 设置父类 Bean 工厂
setParentBeanFactory(parentBeanFactory)
5 AbstractBeanFactory
public void setParentBeanFactory(@Nullable BeanFactory parentBeanFactory) { if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) { throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory); } if (this == parentBeanFactory) { throw new IllegalStateException("Cannot set parent bean factory to self"); } this.parentBeanFactory = parentBeanFactory;}
2 AbstractRefreshableApplicationContext
2-1 定制 BeanFactory
customizeBeanFactory(beanFactory)
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { // 如果属性 allowBeanDefinitionOverriding 不为空,设置给 beanFactory 对象相应属性 if (this.allowBeanDefinitionOverriding != null) { // 设置是否允许覆盖同名称的不同定义的对象 beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } // 如果属性 allowCircularReferences 不为空,设置给 beanFactory 对象相应属性 if (this.allowCircularReferences != null) { // 设置是否允许 bean 之间存在循环依赖 beanFactory.setAllowCircularReferences(this.allowCircularReferences); }}
扩展
这里的两个属性值是可以通过重写子类方法改变值的
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext { public MyClassPathXmlApplicationContext(String... configLocations) { super(configLocations); } @Override protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { // 设置是否允许覆盖同名称的不同定义的对象 super.setAllowBeanDefinitionOverriding(false); // 设置是否允许 bean 之间存在循环依赖 super.setAllowCircularReferences(false); super.customizeBeanFactory(beanFactory); }}
2 AbstractRefreshableApplicationContext
2-1 加载 Bean 定义信息
loadBeanDefinitions(beanFactory)
由于
XmlWebApplicationContext
继承了AbstractRefreshableApplicationContext
,跳转到子类实现。
6 XmlWebApplicationContext
6-1 加载 Bean 定义信息
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // 适配器模式,解析 XML 文件 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 设置环境 beanDefinitionReader.setEnvironment(getEnvironment()); // 设置资源加载器 beanDefinitionReader.setResourceLoader(this); // 设置本地文件库 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 初始化 Bean 定义信息阅读器 initBeanDefinitionReader(beanDefinitionReader); // 加载 Bean 定义信息 loadBeanDefinitions(beanDefinitionReader);}
6-2 解析 XML 文件
XmlBeanDefinitionReader(beanFactory)
7 XmlBeanDefinitionReader
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) { super(registry);}
7-1 父类构造方法
super(registry)
8 AbstractBeanDefinitionReader
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; // Determine ResourceLoader to use. if (this.registry instanceof ResourceLoader) { this.resourceLoader = (ResourceLoader) this.registry; } else { this.resourceLoader = new PathMatchingResourcePatternResolver(); } // Inherit Environment if possible if (this.registry instanceof EnvironmentCapable) { this.environment = ((EnvironmentCapable) this.registry).getEnvironment(); } else { this.environment = new StandardEnvironment(); }}
6 XmlWebApplicationContext
6-2 设置本地文件库
这里就是前面说的读取本地约束文件的实现
ResourceEntityResolver(this)
9 ResourceEntityResolver
public ResourceEntityResolver(ResourceLoader resourceLoader) { super(resourceLoader.getClassLoader()); this.resourceLoader = resourceLoader;}
9-1 父类构造方法
super(resourceLoader.getClassLoader())
10 DelegatingEntityResolver
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) { this.dtdResolver = new BeansDtdResolver(); /** * 在 debug 完成这行代码的调用之后,会发现一件神奇的事情 * schemaResolver 对象的 schemaMappings 属性被完成了赋值 * 但是遍历所有的代码都找不到显示调用 * 原因是 debug 的时候会默认调用对象的 toString() 方法 * schemaResolver 对象的 toString() 方法中调用了 getSchemaMappings() 方法,该方法对 schemaMappings 进行了赋值 */ this.schemaResolver = new PluggableSchemaResolver(classLoader);}
11 PluggableSchemaResolver
public PluggableSchemaResolver(@Nullable ClassLoader classLoader) { this.classLoader = classLoader; this.schemaMappingsLocation = DEFAULT_SCHEMA_MAPPINGS_LOCATION; // META-INF/spring.schemas}
看起来这里就结束了,之所以会给对象赋值,是因为 debug 的时候调用了
toString()
方法。
public String toString() { return "EntityResolver using schema mappings " + getSchemaMappings();}
private MapgetSchemaMappings() { Map schemaMappings = this.schemaMappings; if (schemaMappings == null) { synchronized (this) { schemaMappings = this.schemaMappings; if (schemaMappings == null) { if (logger.isTraceEnabled()) { logger.trace("Loading schema mappings from [" + this.schemaMappingsLocation + "]"); } try { Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader); if (logger.isTraceEnabled()) { logger.trace("Loaded schema mappings: " + mappings); } schemaMappings = new ConcurrentHashMap<>(mappings.size()); CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings); this.schemaMappings = schemaMappings; } catch (IOException ex) { throw new IllegalStateException( "Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex); } } } } return schemaMappings;}
getSchemaMappings()
中给this.schemaMappings
赋了值,所以schemaResolver
对象的schemaMappings
属性被完成了赋值。
6 XmlWebApplicationContext
6-2 初始化 Bean 定义信息阅读器
initBeanDefinitionReader(beanDefinitionReader)
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { }
这里为空,也是供扩展使用。
6-2 加载 Bean 定义信息
loadBeanDefinitions(beanDefinitionReader)
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { // 加载 Bean 定义信息 reader.loadBeanDefinitions(configLocation); } }}
8 AbstractBeanDefinitionReader
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { // 加载 Bean 定义信息 return loadBeanDefinitions(location, null);}
public int loadBeanDefinitions(String location, @Nullable SetactualResources) throws BeanDefinitionStoreException { // 获取 ResourceLoader 对象 ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available"); } if (resourceLoader instanceof ResourcePatternResolver) { try { // 调用 DefaultResourceLoader 的 getResource 方法完成具体的 Resource 定位 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); // 加载 Bean 定义信息 int count = loadBeanDefinitions(resources); if (actualResources != null) { Collections.addAll(actualResources, resources); } if (logger.isTraceEnabled()) { logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]"); } return count; } catch (IOException ex) { throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", ex); } } else { // 只能通过绝对 URL 加载单个资源 Resource resource = resourceLoader.getResource(location); // 加载 Bean 定义信息 int count = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isTraceEnabled()) { logger.trace("Loaded " + count + " bean definitions from location [" + location + "]"); } return count; }}
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int count = 0; for (Resource resource : resources) { // 加载 Bean 定义信息 count += loadBeanDefinitions(resource); } return count;}
7 XmlBeanDefinitionReader
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { // 加载 Bean 定义信息 return loadBeanDefinitions(new EncodedResource(resource));}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isTraceEnabled()) { logger.trace("Loading XML bean definitions from " + encodedResource); } // 通过属性来记录已经加载的数据 SetcurrentResources = this.resourcesCurrentlyBeingLoaded.get(); // 检测是否重复加载 if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } // 从 encodedResource 中获取已经封装的 Resource 对象并再次从 Resource 中获取其中的 inputStream try (InputStream inputStream = encodedResource.getResource().getInputStream()) { // 将 XML 配置文件的 IO 流转为一个 InputSource 对象 InputSource inputSource = new InputSource(inputStream); // 如果资源有编码格式,那就给 inputSource 对象也设置上编码格式 if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } // 进一步加载 Bean 定义信息,逻辑处理的核心步骤 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } catch (IOException ex) { throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { // 从集合中移除资源 currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } }}
7-2 进一步加载 Bean 定义信息
doLoadBeanDefinitions(inputSource, encodedResource.getResource())
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { // 加载文档。获取配置文件加载出来的 Document 对象,这个解析过程是由 documentLoader 完成的 Document doc = doLoadDocument(inputSource, resource); // 注册 Bean 定义信息。将加载出来的文档对象进行解析,定义出相应的 BeanDefinition 对象 int count = registerBeanDefinitions(doc, resource); if (logger.isDebugEnabled()) { logger.debug("Loaded " + count + " bean definitions from " + resource); } return count; } 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); }}
7-3 加载文档
doLoadDocument(inputSource, resource)
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception { // 获取实体解析器 // 获取资源验证模式 // 是否是感知的命名空间 // 加载文档 return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware());}
7-4 获取实体解析器
getEntityResolver()
protected EntityResolver getEntityResolver() { if (this.entityResolver == null) { ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader != null) { this.entityResolver = new ResourceEntityResolver(resourceLoader); } else { this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader()); } } return this.entityResolver;}
if (this.entityResolver == null)
由于前面已经被赋值,直接返回。
7-4 获取资源验证模式
getValidationModeForResource(resource)
protected int getValidationModeForResource(Resource resource) { int validationModeToUse = getValidationMode(); // 如果手动指定了验证模式,则使用指定的验证模式 if (validationModeToUse != VALIDATION_AUTO) { return validationModeToUse; } // 如果没有指定则使用自动检测 int detectedMode = detectValidationMode(resource); if (detectedMode != VALIDATION_AUTO) { return detectedMode; } return VALIDATION_XSD;}
7-4 是否是感知的命名空间
isNamespaceAware()
public boolean isNamespaceAware() { return this.namespaceAware;}
7-4 加载文档
this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware())
12 DefaultDocumentLoader
12-1 加载文档
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception { // 创建文档生成器工厂 DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware); if (logger.isTraceEnabled()) { logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]"); } // 创建文档生成器 DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler); return builder.parse(inputSource);}
12-2 创建文档生成器工厂
createDocumentBuilderFactory(validationMode, namespaceAware)
protected DocumentBuilderFactory createDocumentBuilderFactory(int validationMode, boolean namespaceAware) throws ParserConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(namespaceAware); if (validationMode != XmlValidationModeDetector.VALIDATION_NONE) { factory.setValidating(true); if (validationMode == XmlValidationModeDetector.VALIDATION_XSD) { // Enforce namespace aware for XSD... factory.setNamespaceAware(true); try { factory.setAttribute(SCHEMA_LANGUAGE_ATTRIBUTE, XSD_SCHEMA_LANGUAGE); } catch (IllegalArgumentException ex) { ParserConfigurationException pcex = new ParserConfigurationException( "Unable to validate using XSD: Your JAXP provider [" + factory + "] does not support XML Schema. Are you running on Java 1.4 with Apache Crimson? " + "Upgrade to Apache Xerces (or Java 1.5) for full XSD support."); pcex.initCause(ex); throw pcex; } } } return factory;}
12-2 创建文档生成器
createDocumentBuilder(factory, entityResolver, errorHandler)
protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory, @Nullable EntityResolver entityResolver, @Nullable ErrorHandler errorHandler) throws ParserConfigurationException { DocumentBuilder docBuilder = factory.newDocumentBuilder(); if (entityResolver != null) { docBuilder.setEntityResolver(entityResolver); } if (errorHandler != null) { docBuilder.setErrorHandler(errorHandler); } return docBuilder;}
7 XmlBeanDefinitionReader
7-3 注册 Bean 定义信息
registerBeanDefinitions(doc, resource)
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { // 对 XML 的 BeanDefinition 进行解析 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); // 获取注册表 // 获取 Bean 定义信息加载个数 int countBefore = getRegistry().getBeanDefinitionCount(); // 创建读取的上下文 // 注册 Bean 定义信息,完成具体的解析过程 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); // 记录本次加载的 BeanDefinition 个数 return getRegistry().getBeanDefinitionCount() - countBefore;}
7-4 创建 Bean 定义文档阅读器
createBeanDefinitionDocumentReader()
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() { return BeanUtils.instantiateClass(this.documentReaderClass);}
7-4 获取注册表
getRegistry()
8 AbstractBeanDefinitionReader
public final BeanDefinitionRegistry getRegistry() { return this.registry;}
7 XmlBeanDefinitionReader
7-4 获取 Bean 定义信息加载个数
getBeanDefinitionCount()
13 DefaultListableBeanFactory
public int getBeanDefinitionCount() { return this.beanDefinitionMap.size();}
7 XmlBeanDefinitionReader
7-4 创建读取的上下文
createReaderContext(resource)
public XmlReaderContext createReaderContext(Resource resource) { // 获取命名空间处理程序解析器 return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, getNamespaceHandlerResolver());}
7-5 获取命名空间处理程序解析器
getNamespaceHandlerResolver()
public NamespaceHandlerResolver getNamespaceHandlerResolver() { if (this.namespaceHandlerResolver == null) { // 创建默认命名空间处理程序解析器 this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver(); } return this.namespaceHandlerResolver;}
7-6 创建默认命名空间处理程序解析器
createDefaultNamespaceHandlerResolver()
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() { ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader()); return new DefaultNamespaceHandlerResolver(cl);}
7-4 注册 Bean 定义信息
registerBeanDefinitions(doc, createReaderContext(resource))
14 DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; // 进一步注册 Bean 定义信息 doRegisterBeanDefinitions(doc.getDocumentElement());}
14-1 进一步注册 Bean 定义信息
doRegisterBeanDefinitions(doc.getDocumentElement())
protected void doRegisterBeanDefinitions(Element root) { // 专门处理解析 BeanDefinitionParserDelegate parent = this.delegate; // 获取读取的上下文 // 创建 Bean 定义信息解析器代理 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.isDebugEnabled()) { logger.debug("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;}
14-2 获取读取的上下文
getReaderContext()
protected final XmlReaderContext getReaderContext() { Assert.state(this.readerContext != null, "No XmlReaderContext available"); return this.readerContext;}
14-2 创建 Bean 定义信息解析器代理
createDelegate(getReaderContext(), root, parent)
protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) { BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); // 初始化默认值 delegate.initDefaults(root, parentDelegate); return delegate;}
14-3 初始化默认值
initDefaults(root, parentDelegate)
15 BeanDefinitionParserDelegate
public void initDefaults(Element root, @Nullable BeanDefinitionParserDelegate parent) { // 填充默认值 populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root); // 取消默认注册 this.readerContext.fireDefaultsRegistered(this.defaults);}
15-1 填充默认值
populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root)
protected void populateDefaults(DocumentDefaultsDefinition defaults, @Nullable DocumentDefaultsDefinition parentDefaults, Element root) { String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE); if (isDefaultValue(lazyInit)) { // Potentially inherited from outersections, otherwise falling back to false. lazyInit = (parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE); } defaults.setLazyInit(lazyInit); String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE); if (isDefaultValue(merge)) { // Potentially inherited from outer sections, otherwise falling back to false. merge = (parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE); } defaults.setMerge(merge); String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE); if (isDefaultValue(autowire)) { // Potentially inherited from outer sections, otherwise falling back to 'no'. autowire = (parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE); } defaults.setAutowire(autowire); if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) { defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates()); } if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) { defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setInitMethod(parentDefaults.getInitMethod()); } if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) { defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)); } else if (parentDefaults != null) { defaults.setDestroyMethod(parentDefaults.getDestroyMethod()); } defaults.setSource(this.readerContext.extractSource(root));}
15-1 取消默认注册
private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();fireDefaultsRegistered(this.defaults)
public void fireDefaultsRegistered(DefaultsDefinition defaultsDefinition) { // 默认注册 this.eventListener.defaultsRegistered(defaultsDefinition);}
15-2 默认注册
defaultsRegistered(defaultsDefinition)
private final Listdefaults = new ArrayList<>();public void defaultsRegistered(DefaultsDefinition defaultsDefinition) { this.defaults.add(defaultsDefinition);}
14 DefaultBeanDefinitionDocumentReader
14-2 解析前处理
preProcessXml(root)
protected void preProcessXml(Element root) { }
这里为空,供扩展使用。
14-2 解析 Bean 定义信息
parseBeanDefinitions(root, this.delegate)
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { // 对 bean 的处理 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)) { // 对系统默认标签的处理 parseDefaultElement(ele, delegate); } else { // 对自定义标签的处理 delegate.parseCustomElement(ele); } } } } else { // 对自定义标签的处理 delegate.parseCustomElement(root); }}
14-3 对系统默认标签的处理
parseDefaultElement(ele, delegate)
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { // 对 import 标签的处理 importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { // 对 alias 标签的处理 processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { // 对 bean 标签的处理 processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { // recurse // 对 beans 标签的处理 doRegisterBeanDefinitions(ele); }}
bean 是主要标签,这里重点对它进行分析。
14-4 对 bean 标签的处理
processBeanDefinition(ele, delegate)
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { /** * 解析 Bean 定义元素 * BeanDefinitionHolder 是 beanDefinition 对象的封装类,封装了 BeanDefinition,bean 的名字和别名,用它来完成向 IOC 容器的注册 * 得到这个 BeanDefinitionHolder 就意味着 beanDefinition 是通过 BeanDefinitionParserDelegate 对 XML 元素的信息按照 Spring 的 bean 规则进行解析得到的 */ BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { // 若存在默认标签的子节点下再有自定义属性,还需要再次对自定义标签进行解析 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 向 IOC 容器注册解析得到的 beanDefinition BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // 在 beanDefinition 向 IOC 容器注册完成之后,发送消息 getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); }}
14-5 解析 Bean 定义元素
delegate.parseBeanDefinitionElement(ele)
15 BeanDefinitionParserDelegate
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) { // 解析 Bean 定义元素 return parseBeanDefinitionElement(ele, null);}
15-2 解析 Bean 定义元素
parseBeanDefinitionElement(ele, null)
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) { // 提取出 id 属性值 String id = ele.getAttribute(ID_ATTRIBUTE); // 提取出 name 属性值 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); Listaliases = new ArrayList<>(); // 如果 bean 有别名的话,那么将别名分割解析 if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; // 检查 beanName 是否唯一 if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isTraceEnabled()) { logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } if (containingBean == null) { // 检查标识是否唯一 checkNameUniqueness(beanName, aliases, ele); } // 进一步解析 Bean 定义元素,解析出 beanDefinition 对象 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { // 如果 beanName 属性没有值,则使用默认的规则生成 beanName(默认规则是类名全路径) if (!StringUtils.hasText(beanName)) { try { // 如果不存在 beanName,那么根据 Spring 中提供的命名规则为当前 bean 生成对应的 beanName if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isTraceEnabled()) { logger.trace("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); // 将获取到的信息封装成一个 BeanDefinitionHolder 返回 return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null;}
15-3 检查标识是否唯一
checkNameUniqueness(beanName, aliases, ele)
protected void checkNameUniqueness(String beanName, Listaliases, Element beanElement) { String foundName = null; if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) { foundName = beanName; } if (foundName == null) { foundName = CollectionUtils.findFirstMatch(this.usedNames, aliases); } if (foundName != null) { error("Bean name '" + foundName + "' is already used in this element", beanElement); } this.usedNames.add(beanName); this.usedNames.addAll(aliases);}
15-3 进一步解析 Bean 定义元素
parseBeanDefinitionElement(ele, beanName, containingBean)
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName)); // 解析 class 属性 String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } // 解析出 parent 属性 String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } try { // 创建 Bean 定义信息 AbstractBeanDefinition bd = createBeanDefinition(className, parent); // 解析默认 bean 的各种属性 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); // 从节点中取出 description 属性的值 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); // 解析 meta 元属性 parseMetaElements(ele, bd); // 解析 lookup-method 属性 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); // 解析 replace-method 属性 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); // 解析 constructor-arg 子元素 parseConstructorArgElements(ele, bd); // 解析 property 子元素 parsePropertyElements(ele, bd); // 解析 qualifier 子元素 parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null;}
15-4 创建 Bean 定义信息
createBeanDefinition(className, parent)
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName) throws ClassNotFoundException { // 创建 Bean 定义信息 return BeanDefinitionReaderUtils.createBeanDefinition(parentName, className, this.readerContext.getBeanClassLoader());}
15-5 创建 Bean 定义信息
BeanDefinitionReaderUtils.createBeanDefinition(parentName, className, this.readerContext.getBeanClassLoader())
16 BeanDefinitionReaderUtils
16-1 创建 Bean 定义信息
public static AbstractBeanDefinition createBeanDefinition(@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition(); // parentName 可能为空 bd.setParentName(parentName); if (className != null) { if (classLoader != null) { // 如果 classLoader 不为空,则使用以传入的 classLoader 同一虚拟机加载类对象,否则只是记录 className bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd;}
15 BeanDefinitionParserDelegate
15-4 解析默认 bean 的各种属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd)
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) { if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { // 解析 singleton 属性(该属性已废弃,使用 scope 替代) error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele); } else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { // 解析 scope 属性,如果未指定 scope 属性 bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); } else if (containingBean != null) { // 如果存在 containingBean,则使用 containingBean 的 scope 属性值 bd.setScope(containingBean.getScope()); } // 解析 abstract 属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } // 解析 lazy-init 属性 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (isDefaultValue(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } // 若没有设置或设置成其他字符都会被设置成 false bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); // 解析 autowire 属性 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); // 解析 depends-on 属性 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } // 解析 autowire-candidate 属性 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if (isDefaultValue(autowireCandidate)) { String candidatePattern = this.defaults.getAutowireCandidates(); if (candidatePattern != null) { String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern); bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName)); } } else { bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate)); } // 解析 primary 属性 if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } // 解析 init-method 属性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); bd.setInitMethodName(initMethodName); } else if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } // 解析 destroy-method 属性 if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) { String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE); bd.setDestroyMethodName(destroyMethodName); } else if (this.defaults.getDestroyMethod() != null) { bd.setDestroyMethodName(this.defaults.getDestroyMethod()); bd.setEnforceDestroyMethod(false); } // 解析 factory-method 属性 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } // 解析 factory-bean 属性 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd;}
15 BeanDefinitionParserDelegate
15-4 解析 meta 元属性
parseMetaElements(ele, bd)
public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) { // 获取当前节点的所有子元素 NodeList nl = ele.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); // 提取 meta if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) { Element metaElement = (Element) node; String key = metaElement.getAttribute(KEY_ATTRIBUTE); String value = metaElement.getAttribute(VALUE_ATTRIBUTE); // 使用 key-value 构造 BeanMetadataAttribute BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value); attribute.setSource(extractSource(metaElement)); // 记录信息 attributeAccessor.addMetadataAttribute(attribute); } }}
15-4 解析 lookup-method 属性
parseLookupOverrideSubElements(ele, bd.getMethodOverrides())
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); // 仅当在 Spring 默认 bean 的子元索下且为
15-4 解析 replace-method 属性
parseReplacedMethodSubElements(ele, bd.getMethodOverrides())
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); // 仅当在 Spring 默认 bean 的子元素下且为argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT); // 解析 arg-type for (Element argTypeEle : argTypeEles) { // 记录参数 String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE); match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle)); if (StringUtils.hasText(match)) { replaceOverride.addTypeIdentifier(match); } } replaceOverride.setSource(extractSource(replacedMethodEle)); overrides.addOverride(replaceOverride); } }}
15-4 解析 constructor-arg
parseConstructorArgElements(ele, bd)
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT)) { // 解析 constructor-arg parseConstructorArgElement((Element) node, bd); } }}
public void parseConstructorArgElement(Element ele, BeanDefinition bd) { // 先获取 name、index 以及 value 属性,因为构造方法的参数可以指定 name,也可以指定下标 String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE); String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE); String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); // 判断 index 是否有值,进而决定按照 index 解析还是按照 name 解析 if (StringUtils.hasLength(indexAttr)) { try { int index = Integer.parseInt(indexAttr); if (index < 0) { error("'index' cannot be lower than 0", ele); } else { try { this.parseState.push(new ConstructorArgumentEntry(index)); // 解析 ele 对应的属性元素 Object value = parsePropertyValue(ele, bd, null); // 封装解析出来的元素 ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value); if (StringUtils.hasLength(typeAttr)) { valueHolder.setType(typeAttr); } if (StringUtils.hasLength(nameAttr)) { valueHolder.setName(nameAttr); } valueHolder.setSource(extractSource(ele)); // 不允许重复指定相同参数 if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) { error("Ambiguous constructor-arg entries for index " + index, ele); } else { // 保存解析结果 bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder); } } finally { this.parseState.pop(); } } } catch (NumberFormatException ex) { error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele); } } else { // 没有 index 属性则自动寻找 try { this.parseState.push(new ConstructorArgumentEntry()); // 解析 constructor-arg 子元素 Object value = parsePropertyValue(ele, bd, null); ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value); if (StringUtils.hasLength(typeAttr)) { valueHolder.setType(typeAttr); } if (StringUtils.hasLength(nameAttr)) { valueHolder.setName(nameAttr); } valueHolder.setSource(extractSource(ele)); // 保存解析结果 bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder); } finally { this.parseState.pop(); } }}
15-4 解析 property 子元素
parsePropertyElements(ele, bd)
public void parsePropertyElements(Element beanEle, BeanDefinition bd) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) { // 解析 property 子元素 parsePropertyElement((Element) node, bd); } }}
public void parsePropertyElement(Element ele, BeanDefinition bd) { // 获取配置元素中 name 的值 String propertyName = ele.getAttribute(NAME_ATTRIBUTE); if (!StringUtils.hasLength(propertyName)) { error("Tag 'property' must have a 'name' attribute", ele); return; } this.parseState.push(new PropertyEntry(propertyName)); try { // 不允许多次对同一属性配置。如果已经存在同名的 property 属性,那么就不进行解析 if (bd.getPropertyValues().contains(propertyName)) { error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } /** * 此处用来解析 property 值,返回的对象对应对 bean 定义的 property 属性设置的解析结果 * 这个解析结果会封装到 PropertyValue 对象中,然后设置到 BeanDefinitionHolder 中去 */ Object val = parsePropertyValue(ele, bd, propertyName); PropertyValue pv = new PropertyValue(propertyName, val); parseMetaElements(ele, pv); pv.setSource(extractSource(ele)); bd.getPropertyValues().addPropertyValue(pv); } finally { this.parseState.pop(); }}
15-4 解析 qualifier 子元素
parseQualifierElements(ele, bd)
public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) { // 解析 qualifier 子元素 parseQualifierElement((Element) node, bd); } }}
public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) { String typeName = ele.getAttribute(TYPE_ATTRIBUTE); if (!StringUtils.hasLength(typeName)) { error("Tag 'qualifier' must have a 'type' attribute", ele); return; } this.parseState.push(new QualifierEntry(typeName)); try { AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName); qualifier.setSource(extractSource(ele)); String value = ele.getAttribute(VALUE_ATTRIBUTE); if (StringUtils.hasLength(value)) { qualifier.setAttribute(AutowireCandidateQualifier.VALUE_KEY, value); } NodeList nl = ele.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) { Element attributeEle = (Element) node; String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE); String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE); if (StringUtils.hasLength(attributeName) && StringUtils.hasLength(attributeValue)) { BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue); attribute.setSource(extractSource(attributeEle)); qualifier.addMetadataAttribute(attribute); } else { error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle); return; } } } bd.addQualifier(qualifier); } finally { this.parseState.pop(); }}
14 DefaultBeanDefinitionDocumentReader
14-3 对自定义标签的处理
delegate.parseCustomElement(ele)
15 BeanDefinitionParserDelegate
public BeanDefinition parseCustomElement(Element ele) { // 解析自定义元素 return parseCustomElement(ele, null);}
15-1 解析自定义元素
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { // 获取对应的命名空间 String namespaceUri = getNamespaceURI(ele); if (namespaceUri == null) { return null; } // 根据命名空间找到对应的处理者 // 处理命名空间 NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } // 调用自定义的 NamespaceHandler 进行解析 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}
15-2 获取对应的命名空间
getNamespaceURI(ele)
public String getNamespaceURI(Node node) { return node.getNamespaceURI();}
15-2 根据命名空间找到对应的处理者
getNamespaceHandlerResolver()
18 XmlReaderContext
private final NamespaceHandlerResolver namespaceHandlerResolver;public final NamespaceHandlerResolver getNamespaceHandlerResolver() { return this.namespaceHandlerResolver;}
15-2 处理命名空间
resolve(namespaceUri)
19 DefaultNamespaceHandlerResolver
public NamespaceHandler resolve(String namespaceUri) { // 获取所有已经配置的 handler 映射 MaphandlerMappings = getHandlerMappings(); // 根据命名空间找到对应的信息 Object handlerOrClassName = handlerMappings.get(namespaceUri); if (handlerOrClassName == null) { return null; } else if (handlerOrClassName instanceof NamespaceHandler) { // 已经做过解析的情况,直接从缓存读取 return (NamespaceHandler) handlerOrClassName; } else { // 没有做过解析,则返回的是类路径 String className = (String) handlerOrClassName; try { // 使用反射将类路径转化为类 Class handlerClass = ClassUtils.forName(className, this.classLoader); if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri + "] does not implement the [" + NamespaceHandler.class.getName() + "] interface"); } // 初始化类 NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); // 调用自定义的 NamespaceHandler 的初始化方法 namespaceHandler.init(); // 记录在缓存 handlerMappings.put(namespaceUri, namespaceHandler); return namespaceHandler; } catch (ClassNotFoundException ex) { throw new FatalBeanException("Could not find NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", ex); } catch (LinkageError err) { throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" + className + "] for namespace [" + namespaceUri + "]", err); } }}
19-1 获取所有已经配置的 handler 映射
getHandlerMappings()
private MapgetHandlerMappings() { Map handlerMappings = this.handlerMappings; // 如果没有被缓存则开始进行缓存 if (handlerMappings == null) { synchronized (this) { handlerMappings = this.handlerMappings; if (handlerMappings == null) { if (logger.isTraceEnabled()) { logger.trace("Loading NamespaceHandler mappings from [" + this.handlerMappingsLocation + "]"); } try { // this.handlerMappingsLocation 在构造函数中已经被初始化为 META-INF/Spring.handlers Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader); if (logger.isTraceEnabled()) { logger.trace("Loaded NamespaceHandler mappings: " + mappings); } handlerMappings = new ConcurrentHashMap<>(mappings.size()); // 将 Properties 格式文件合并到 Map 格式的 handlerMappings 中 CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings); this.handlerMappings = handlerMappings; } catch (IOException ex) { throw new IllegalStateException( "Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex); } } } } return handlerMappings;}
15 BeanDefinitionParserDelegate
15-2 调用自定义的 NamespaceHandler 进行解析
parse(ele, new ParserContext(this.readerContext, this, containingBd))
20 NamespaceHandlerSupport
public BeanDefinition parse(Element element, ParserContext parserContext) { // 寻找解析器并进行解析操作 BeanDefinitionParser parser = findParserForElement(element, parserContext); return (parser != null ? parser.parse(element, parserContext) : null);}
20-1 寻找解析器并进行解析操作
findParserForElement(element, parserContext)
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) { // 获取自定义标签的元素名称 String localName = parserContext.getDelegate().getLocalName(element); // 注册的解析器 BeanDefinitionParser parser = this.parsers.get(localName); if (parser == null) { parserContext.getReaderContext().fatal( "Cannot locate BeanDefinitionParser for element [" + localName + "]", element); } return parser;}
14 DefaultBeanDefinitionDocumentReader
14-2 解析后处理
postProcessXml(root)
protected void postProcessXml(Element root) { }
这里为空,留给子类扩展。
1 AbstractApplicationContext
1-2 返回当前实体的 beanFactory 属性
getBeanFactory()
2 AbstractRefreshableApplicationContext
public final ConfigurableListableBeanFactory getBeanFactory() { DefaultListableBeanFactory beanFactory = this.beanFactory; if (beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return beanFactory;}
if (beanFactory == null)
由于已经定义了 beanFactory,这里直接返回值。