博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码 07 IOC refresh方法2
阅读量:37194 次
发布时间:2020-08-01

本文共 52165 字,大约阅读时间需要 173 分钟。

参考源

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


Spring IOC 的核心是 AbstractApplicationContextrefresh 方法。

其中一共有 13 个主要方法,这里分析第 2 个: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 Map
getSchemaMappings() { 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 Set
actualResources) 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);   }   // 通过属性来记录已经加载的数据   Set
currentResources = 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 outer 
sections, 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 List
defaults = 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);   List
aliases = 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, List
aliases, 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 映射   Map
handlerMappings = 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 Map
getHandlerMappings() { 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,这里直接返回值。

转载地址:http://aupwwy.baihongyu.com/

你可能感兴趣的文章
java和python交互 jni_Python基于pyjnius库实现访问java类
查看>>
macbook pro 卸载mysql_MacBook Pro全新重装OS X Yosemite
查看>>
已达到计算机的连接数最大值无法再同此远程计算机连接_电脑远程访问已达到计算机的连接数最大值怎么办?解决方法很简单...
查看>>
mysql表名长度_JavaWeb之MySQL(一)
查看>>
mysql服务器语法_Mysql语法
查看>>
pdf 模版 汉字和数字_《吉林大学珠海学院毕业论文(设计)模板》(汉字标题版) .pdf...
查看>>
python bottle部署_nginx+uwsgi+bottle python服务器部署
查看>>
python双击py一闪_Python脚本在双击.py时无法正常运行
查看>>
redis logfile为空_关于Redis(二)
查看>>
mysql 设计两个主键都不可重复_程序员面试备战篇:18个经典MySQL面试专题解析(干货分享答案)...
查看>>
下列关于python2.x和3.x的区别说法正确_Python 2.x和Python 3.x版本有哪些区别?【面试题详解】...
查看>>
git更换_git命令
查看>>
hp-ux 查看系统负载_Linux性能调优 | 平均负载的理解和分析
查看>>
elementui的tree组件页面显示不出数据_vue路由及组件
查看>>
android hook sensor数据_最近,又有人在谈论Android的前景了!深入解析趋势及必备技术点...
查看>>
python 动态tabel的数据爬取_使用requests爬取python岗位招聘数据
查看>>
input js number 整数_JS基础简单小结(1)
查看>>
二阶差分预测后数据还原公式_xgboost系列丨xgboost原理及公式推导
查看>>
docker mysql服务启动失败_docker中mysql初始化及启动失败问题解决方案
查看>>
mysql 阿里云 添加磁盘空间_rds mysql磁盘空间包含
查看>>