逻辑不复杂,主要是对 beanName 和该 BeanDefinition 对象的校验,最终将其映射保存在 beanDefinitionMap 中(ConcurrentHashMap),key 就是 beanName
9. 注册 alias 别名 // org.springframework.core.SimpleAliasRegistry @Override public void registerAlias(String name, String alias) { // 校验 name 、 alias Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); synchronized (this.aliasMap) { // name == alias 则去掉alias if (alias.equals(name)) { this.aliasMap.remove(alias); if (logger.isDebugEnabled()) { logger.debug("Alias definition '" + alias + "' ignored since it points to same name"); } } else { // 获取 alias 已注册的 beanName String registeredName = this.aliasMap.get(alias); // 已存在 if (registeredName != null) { // 相同,则 return ,无需重复注册 if (registeredName.equals(name)) { // An existing alias - no need to re-register return; } // 不允许覆盖,则抛出 IllegalStateException 异常 if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } if (logger.isDebugEnabled()) { logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'"); } } // 校验,是否存在循环指向 checkForAliasCircle(name, alias); // 注册 alias this.aliasMap.put(alias, name); if (logger.isTraceEnabled()) { logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'"); } } } }逻辑不复杂,将 alias 与 beanName 映射保存至 aliasMap 中(ConcurrentHashMap)
总结解析出 XML 文件中的 BeanDefinition 并注册的整个过程大致如下:
根据 XSD 文件对 XML 文件进行校验
将 XML 文件资源转换成 org.w3c.dom.Document 对象
根据 Document 对象解析 <beans /> 标签,遍历所有的子标签
如果是子标签是默认的命名空间(为空或者 )则进行处理,例如:<import>、<alias />、<bean />和<beans />,其中 <bean /> 会被解析出一个 GenericBeanDefinition 对象,然后进行注册
否则,找到对应的 NamespaceHandler 对象进行解析,例如:<context:component-scan /> 、<context:annotation-config />、<util:list />,这些非默认命名空间的标签都会有对应的 BeanDefinitionParser 解析器
至此,我们通过 XML 文件定义的 Bean 已经转换成了 Bean 的“前身”,也就是 BeanDefinition 对象。接下来会分析在 XML 文件中,非默认命名空间的标签是如何进行处理的。