Spirng 源代码学习笔记 Web 篇(二)HandlerMapping

2 篇文章 0 订阅

Spirng 源代码学习笔记 Web 篇(二)HandlerMapping

HandlerMapping 负责将请求映射到实际处理对象。

 

当应用上下文中未配置 HandlerMapping 的实现类时,DispatcherServlet 在初始化时会根据DispatcherServlet.properties 的配置设置 Spring 自己的实现类。 

 

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

 

继承结构:


 

HandlerMapping

接口声明如下,入参为 request 对象,返回为 HandlerExecutionChain。 

 

HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

  

HandlerExecutionChain 包含实际处理请求的对象和拦截器。实际处理请求的对象例子是普通的 Controller 对象;拦截器的例子:如对 http 返回设置统一的防止浏览器缓存头信息。

 

AbstractHandlerMapping

继承自 WebApplicationObjectSupport,支持 ordering, a default handler, and handler interceptors.

使用 template method:

 

	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = getApplicationContext().getBean(handlerName);
		}
		return getHandlerExecutionChain(handler, request);
	}
	
	protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;
	
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		if (handler instanceof HandlerExecutionChain) {
			HandlerExecutionChain chain = (HandlerExecutionChain) handler;
			chain.addInterceptors(getAdaptedInterceptors());
			return chain;
		}
		else {
			return new HandlerExecutionChain(handler, getAdaptedInterceptors());
		}
	}
 

 

AbstractUrlHandlerMapping

for URL-mapped。Provides infrastructure for mapping handlers to URLs;

Supports direct matches and various Ant-style pattern matches。

 

// 注册映射关系

protected void registerHandler(String urlPath, Object handler)

 

// 根据已注册的映射集合找到所有匹配项,并确定一个 best match

protected Object lookupHandler(String urlPath, HttpServletRequest request)

 

// 调用 lookupHandler,设置拦截器,返回 HandlerExecutionChain

protected Object getHandlerInternal(HttpServletRequest request)

 

SimpleUrlHandlerMapping

根据用户配置的 Map<String, Object> 集合,注册映射集合。

 

AbstractDetectingUrlHandlerMapping

扫描所有 spring 上下文中的 bean 实例,存在映射的自动进行注册。

再次 template method:

 

	protected void detectHandlers() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
		}
		String[] beanNames = (this.detectHandlersInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
				getApplicationContext().getBeanNamesForType(Object.class));

		// Take any bean name that we can determine URLs for.
		for (String beanName : beanNames) {
			String[] urls = determineUrlsForHandler(beanName);
			if (!ObjectUtils.isEmpty(urls)) {
				// URL paths found: Let's consider it a handler.
				registerHandler(urls, beanName);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Rejected bean name '" + beanName + "': no URL paths identified");
				}
			}
		}
	}
	protected abstract String[] determineUrlsForHandler(String beanName);
 

 

BeanNameUrlHandlerMapping

beanName 映射,只处理以 “/” 开始的 beanName。

	protected String[] determineUrlsForHandler(String beanName) {
		List<String> urls = new ArrayList<String>();
		if (beanName.startsWith("/")) {
			urls.add(beanName);
		}
		String[] aliases = getApplicationContext().getAliases(beanName);
		for (String alias : aliases) {
			if (alias.startsWith("/")) {
				urls.add(alias);
			}
		}
		return StringUtils.toStringArray(urls);
	}
 

 

DefaultAnnotationHandlerMapping

类和方法上 RequestMapping 注解中的 value 值作为 url 的构成部分。

 

AbstractControllerUrlHandlerMapping

基于约定,面向 Controller 类型的映射。可配置不希望包含的类或者包。

Controller 类型是指实现了 org.springframework.web.servlet.mvc.Controller 接口或者类上使用了 @Controller 注解。

 

ControllerBeanNameHandlerMapping

根据 beanName 和配置的前缀、后缀作为映射的 url。

 

ControllerClassNameHandlerMapping

根据类的名称生成 url,可配置大小写敏感、路径前缀、basePackage。

org.springframework.web.servlet.mvc.Controller

  • WelcomeController -> /welcome*
  • HomeController -> /home*

For MultiActionControllers and @Controller beans

  • WelcomeController -> /welcome, /welcome/*
  • CatalogController -> /catalog, /catalog/*
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值