2.2、spring之xml文件转换为BeanDefinition

一 、过程

1.1 根据schema获取对应的处理器

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      ">
    <!-- Enables the Spring MVC @Controller programming model -->
    <mvc:annotation-driven/>
</beans>

在上面的时候我们使用了mvc的schema,那么对于spring,是由哪个类来处理这个schema的呢?又是根据什么来查找到这个对应的处理类呢?

我们知道mvc的schema是由MvcNamespaceHandler这个类进行处理的。那么spring是如何将mvc的schema映射到对应的处理类的呢。

在这里插入图片描述
在spring 中存在一个NamespaceHandlerResolver接口,只有一个方法,根据schema来解析到对应的处理器。同时有一个默认的实现类。我们来看一下默认的实现类。

public NamespaceHandler resolve(String namespaceUri) {
        // 1、获取所有的映射
		Map<String, Object> handlerMappings = getHandlerMappings();
		// 获取映射对应的类名称
		Object handlerOrClassName = handlerMappings.get(namespaceUri);
		if (handlerOrClassName == null) {
			return null;
		}
		else if (handlerOrClassName instanceof NamespaceHandler) {
		    // 2、如果类是NamespaceHandler的实现类,直接返回
			return (NamespaceHandler) handlerOrClassName;
		}
		else {
		     // 3、根据类名称实例化NamespaceHandler的类,并存储到映射的map。
			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.init();
				handlerMappings.put(namespaceUri, namespaceHandler);
				return namespaceHandler;
			}
			catch (ClassNotFoundException ex) {
				throw new FatalBeanException("NamespaceHandler class [" + className + "] for namespace [" +
						namespaceUri + "] not found", ex);
			}
			catch (LinkageError err) {
				throw new FatalBeanException("Invalid NamespaceHandler class [" + className + "] for namespace [" +
						namespaceUri + "]: problem with handler class file or dependent class", err);
			}
		}
	}

从中我们可以看到最重要的方法是getHandlerMappings();深入到该方法中

    if (this.handlerMappings == null) {
			synchronized (this) {
				if (this.handlerMappings == null) {
					try {
					   // 1、载入所有的Properties
						Properties mappings =
								PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
						if (logger.isDebugEnabled()) {
							logger.debug("Loaded NamespaceHandler mappings: " + mappings);
						}
						// 2、将Properties合并为Map
						Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
						CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
						this.handlerMappings = handlerMappings;
					}
					catch (IOException ex) {
						throw new IllegalStateException(
								"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
					}
				}
			}
		}
		return this.handlerMappings;

我们看一下载入的时候handlerMappingsLocation的值。

public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";

由此,我们确定到xml的schema和对schema的映射关系是写死在spring.handlers文件中的。我们可以再看一下spring.handlers文件中是如何进行存储的。

http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler

现在我们确定了schema和处理器的关系,那么处理器又是如何对schema中的内容进行处理的呢?

1.2 处理器处理信息

在这里插入图片描述
对于NamespaceHandler,我们可以看到有三个方法,初始化、解析元素信息、包装信息。init()方法在类初始化后被调用(参考上方对于Handler的查找和初始化)。

public class MvcNamespaceHandler extends NamespaceHandlerSupport {

	public void init() {
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
		registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
		registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
		registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
	}

}

我们可以看一下对于mvc的handler处理器。可以看到建立了一级元素和Parser的映射关系。那么我们可以看一下Parser的处理,Parser是对xml的硬编码解析。

1.3 硬编码解析xml文件


对于BeanDefinitionParser接口,只有一个方法parse,返回信息为BeanDefinition。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值