spring 之 import标签、alias标签、beans标签 解析
2017-09-28 13:42
661 查看
继续接着Spring 加载、解析applicationContext.xml 流程解析 import 、 alias、beans 标签。
DefaultBeanDefinitionDocumentReader.parseDefaultElement()
获取resource属性
解析路径中的系统属性,格式如“${user.dir}”
判断location是绝对路径还是相对路径
如果是绝对路径,则递归调用bean的解析过程。重新执行这个流程 Spring 加载、解析applicationContext.xml 流程
如果相对路径,则把相对路径转换成绝对路径,在解析
通过监听器、解析完成
解析 alias 标签,获取 name 和 alias 属性值。
把 name 和 alias 注册到 SimpleAliasRegistry.aliasMap 属性中。
beans 标签解析 又调用了doRegisterBeanDefinitions() 方法,这个方法在Spring 加载、解析applicationContext.xml 流程中已经介绍过了。
跟import 解析都类似。又相当于重新执行解析了一边 bean 标签一样。
本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8
点击这里快速进入简书
GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT
DefaultBeanDefinitionDocumentReader.parseDefaultElement()
1. import 标签解析
标签示例
<import resource="user-appalicationContext.xml"/>
解析import 标签
入口类、方法DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource();protected void importBeanDefinitionResource(Element ele) { // 解析 resource 属性 String location = ele.getAttribute(RESOURCE_ATTRIBUTE); //如果为空,不做处理 if (!StringUtils.hasText(location)) { getReaderContext().error("Resource location must not be empty", ele); return; } // 解析系统属性。比如 "${user.dir}" location = getReaderContext().getEnvironment().resolveRequiredPlaceholders(location); Set<Resource> actualResources = new LinkedHashSet<>(4); boolean absoluteLocation = false; try { // 判断 location 是绝对路径还是相对路径 absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute(); }catch (URISyntaxException ex) { // cannot convert to an URI, considering the location relative // unless it is the well-known Spring prefix "classpath*:" } // 绝对路径 if (absoluteLocation) { try { //加载xml配置文件,并解析资源 int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources); if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]"); } }catch (BeanDefinitionStoreException ex) { getReaderContext().error( "Failed to import bean definitions from URL location [" + location + "]", ele, ex); } }else { // No URL -> considering resource location as relative to the current file. try { int importCount; //获取绝对路径,并解析文件 Resource relativeResource = getReaderContext().getResource().createRelative(location); if (relativeResource.exists()) { //加载xml文件,并解析 importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource); actualResources.add(relativeResource); }else { // 获取URL 路径,并解析文件 String baseLocation = getReaderContext().getResource().getURL().toString(); importCount = getReaderContext().getReader().loadBeanDefinitions( StringUtils.applyRelativePath(baseLocation, location), actualResources); } if (logger.isDebugEnabled()) { logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]"); } } catch (IOException ex) { getReaderContext().error("Failed to resolve current resource location", ele, ex); }catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]", ele, ex); } } Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]); getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele)); }
获取resource属性
解析路径中的系统属性,格式如“${user.dir}”
判断location是绝对路径还是相对路径
如果是绝对路径,则递归调用bean的解析过程。重新执行这个流程 Spring 加载、解析applicationContext.xml 流程
如果相对路径,则把相对路径转换成绝对路径,在解析
通过监听器、解析完成
2. alias 标签解析
alias 标签示例
<bean id="user" class="cn.com.infcn.test.User"></bean> <alias name="user" alias="myUser" />
解析 alias 标签
DefaultBeanDefinitionDocumentReader.processAliasRegistration()protected void processAliasRegistration(Element ele) { //获取 name属性 String name = ele.getAttribute(NAME_ATTRIBUTE); //获取 alias 属性 String alias = ele.getAttribute(ALIAS_ATTRIBUTE); boolean valid = true; //验证 name 是否为空 if (!StringUtils.hasText(name)) { getReaderContext().error("Name must not be empty", ele); valid = false; } //验证 alias 是否为空 if (!StringUtils.hasText(alias)) { getReaderContext().error("Alias must not be empty", ele); valid = false; } if (valid) { try { //把 alias 注册到 SimpleAliasRegistry.aliasMap 中 getReaderContext().getRegistry().registerAlias(name, alias); } catch (Exception ex) { getReaderContext().error("Failed to register alias '" + alias + "' for bean with name '" + name + "'", ele, ex); } getReaderContext().fireAliasRegistered(name, alias, extractSource(ele)); } }
解析 alias 标签,获取 name 和 alias 属性值。
把 name 和 alias 注册到 SimpleAliasRegistry.aliasMap 属性中。
SimpleAliasRegistry 源码
public class SimpleAliasRegistry implements AliasRegistry { private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16); @Override public void registerAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); if (alias.equals(name)) { this.aliasMap.remove(alias); }else { String registeredName = this.aliasMap.get(alias); if (registeredName != null) { if (registeredName.equals(name)) { // An existing alias - no need to re-register return; } if (!allowAliasOverriding()) { throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } } checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); } } protected boolean allowAliasOverriding() { return true; } ......
3. beans 标签解析
beans标签示例
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="user" class="cn.com.infcn.test.User"></bean> <beans> ...... </beans> </beans>
beans 标签解析 又调用了doRegisterBeanDefinitions() 方法,这个方法在Spring 加载、解析applicationContext.xml 流程中已经介绍过了。
跟import 解析都类似。又相当于重新执行解析了一边 bean 标签一样。
本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8
点击这里快速进入简书
GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT
相关文章推荐
- spring源码附录(8)import、beans标签的解析
- bean标签的解析及注册(四)对alias,import,beans标签的处理
- spring 3源码解析之如何解析"import", "alias", "bean"标签
- 4.2 spring-import 标签的解析;
- 4.3 spring-嵌入式beans标签的解析
- 【死磕 Spring】—– IOC 之解析Bean:解析 import 标签
- 使用import简化spring的配置 spring import 标签的解析 使用import或加载spring配置时,报错误There is no ID/IDREF 多个Spring配置文件import resource路径配置
- spring源码(7)alias标签的解析
- 4.1 spring-alias 标签的解析;
- Spring事务解析2-标签解析
- spring 源码探索 -- aop 标签解析和创建代理
- Eclipse无法解析导入 org.springframework.stereotype或者beans
- 6.2 dubbo在spring中自定义xml标签源码解析
- 【死磕 Spring】----- IOC 之解析 bean 标签:开启解析进程
- SSH问题:系统启动时,spring配置文件解析失败,报”cvc-elt.1: 找不到元素 'beans' 的声明“异常
- spring源码剖析(四)自定义标签解析流程
- spring源码(6)bean标签其他子标签的解析
- Spring4.3.x 浅析xml配置的解析过程(11)——解析aop命名空间之scoped-proxy标签
- spring中alias标签
- spring beans 标签