AbstractHandlerMapping类详解 - HandlerMapping系列一

AbstractHandlerMapping是HandlerMapping的抽象实现,所有的HandlerMapping都继承自AbstractHandlerMapping,下面详解介绍它最重要的方法。

initApplicationContext() 初始化

private final Listinterceptors = new ArrayList();
private final ListadaptedInterceptors = new ArrayList();
private final ListmappedInterceptors = new ArrayList();
@Override
protected void initApplicationContext() throws BeansException {
	//模板方法,用于给子类提供一个添加Interceptors的入口。
	extendInterceptors(this.interceptors);
	//将SpringMvc容器和父容器中所有的MappedInterceptor类型的Bean添加到mappedInterceptors的属性
	detectMappedInterceptors(this.mappedInterceptors);
        //用于初始化Interceptor,将Interceptors属性里所包含的对象按类型添加到mappedInterceptors和adaptedInterceptors.
	initInterceptors();
}

AbstractHandlerMapping通过initApplicationContext()方法进行自动初始化,它的创建其实就是初始化上面三个interceptor,其一般是由父类执行ApplicationContextAware#setApplicationContext()方法间接调用,主要是获取springmvc上下文中的拦截器集合MappedInterceptor。

getHandler() 获取处理链对象

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
	//getHandlerInternal(request)方法为抽象方法,供子类实现
	//获取到的handler对象一般为bean/HandlerMethod
	Object handler = getHandlerInternal(request);
	//上述找不到则使用默认的处理类,没有设定则返回null,则会返回前台404错误
	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);
	}
	//创建处理链对象
	HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
	//针对cros跨域请求的处理,此处就不分析了
	if (CorsUtils.isCorsRequest(request)) {
		CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
		CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
		CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
		executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
	}
	return executionChain;
}
//针对HandlerMethod的获取
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
	//获取访问的路径,一般类似于request.getServletPath()返回不含contextPath的访问路径
	String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
	
	//获取读锁
	this.mappingRegistry.acquireReadLock();
	try {
		//获取HandlerMethod作为handler对象,这里涉及到路径匹配的优先级
		//优先级:精确匹配>最长路径匹配>扩展名匹配
		HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
		//HandlerMethod内部含有bean对象,其实指的是对应的Controller
		return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
	}
	finally {
		//释放读锁
		this.mappingRegistry.releaseReadLock();
	}
}
//针对beanName的获取
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
	String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
	//从handlerMap查找路径对应的beanName
	Object handler = lookupHandler(lookupPath, request);
	if (handler == null) {
		// We need to care for the default handler directly, since we need to
		// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
		Object rawHandler = null;
		if ("/".equals(lookupPath)) {
			rawHandler = getRootHandler();
		}
		if (rawHandler == null) {
			rawHandler = getDefaultHandler();
		}
		if (rawHandler != null) {
			// Bean name or resolved handler?
			if (rawHandler instanceof String) {
				String handlerName = (String) rawHandler;
				rawHandler = getApplicationContext().getBean(handlerName);
			}
			validateHandler(rawHandler, request);
			handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
		}
	}
	
	return handler;
}

HandlerMapping是通过getHandler方法来获取处理器Handler和拦截器Interceptors的,AbstractHandlerMapping实现获取handler。

getHandlerExecutionChain() 创建处理链对象

//真实处理请求对象
private final Object handler;
//拦截器集合
private HandlerInterceptor[] interceptors;
//拦截器集合
private ListinterceptorList;
//拦截器开始下标,默认正序执行
private int interceptorIndex = -1;
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
	//创建HandlerExecutionChain
	HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
			(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
	//添加所有AdaptedInterceptor的拦截器
	chain.addInterceptors(getAdaptedInterceptors());
	
	String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
	//与请求url进行匹配,满足的才加入
	for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) {
		if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
			chain.addInterceptor(mappedInterceptor.getInterceptor());
		}
	}

	return chain;
}

getHandlerExecutionChain之前用于找Handler,之后用于添加拦截器。getHandlerExecutionChain的实现使用handler创建出HandlerExecutionChain类型的变量,然后将adaptedInterceptors和符合要求的mappedInterceptors添加进去,最后将其返回。

1. HandlerExecutionChain处理链内部含有handler对象,可为@RequestMapping对应的HandlerMethod对象,也可为springmvc上下文的beanName

2. HandlerExecutionChain处理链内部主要包含拦截器对象,其可从springmvc上下文获取HandlerInterceptor/MappedHandlerInterceptor类型作为内部集合;

setOrder/getOrder() 设置执行顺序

//设置不同HandlerMapping实现类的执行顺序  
public final void setOrder(int order) {  
  this.order = order;  
}  

@Override  
public final int getOrder() {  
  return this.order;  
}

initApplicationContext() 拦截器初始化

//初始化时调用,初始化一些基本信息,这里主要是初始化一些拦截器  
@Override  
protected void initApplicationContext() throws BeansException {  
	extendInterceptors(this.interceptors);//添加或修车intercept,现在并没有具体实现  
	detectMappedInterceptors(this.adaptedInterceptors);//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中  
	initInterceptors();  
}  

protected void extendInterceptors(Listinterceptors) {  
}  

//将springMVC容器或者父容器中的所有MappedInterceptor类型的Bean添加到mappedInterceptors属性中  
protected void detectMappedInterceptors(ListmappedInterceptors) {  
	mappedInterceptors.addAll(  
			BeanFactoryUtils.beansOfTypeIncludingAncestors(  
					getApplicationContext(), MappedInterceptor.class, true, false).values());  
}  

//初始化Interceptor,将interceptors属性里所包含的对象按类型添加到mappedInterceptors或者adaptedInterceptors中。  
protected void initInterceptors() {  
	if (!this.interceptors.isEmpty()) {  
		for (int i = 0; i < this.interceptors.size(); i++) { Object interceptor = this.interceptors.get(i); if (interceptor == null) { throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null"); } this.adaptedInterceptors.add(adaptInterceptor(interceptor)); } } } protected HandlerInterceptor adaptInterceptor(Object interceptor) { if (interceptor instanceof HandlerInterceptor) { return (HandlerInterceptor) interceptor; } else if (interceptor instanceof WebRequestInterceptor) { return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor); } else { throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName()); } } protected final HandlerInterceptor[] getAdaptedInterceptors() { int count = this.adaptedInterceptors.size(); return (count > 0 ? this.adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null);  
}  

protected final MappedInterceptor[] getMappedInterceptors() {  
	ListmappedInterceptors = new ArrayList();  
	for (HandlerInterceptor interceptor : this.adaptedInterceptors) {  
		if (interceptor instanceof MappedInterceptor) {  
			mappedInterceptors.add((MappedInterceptor) interceptor);  
		}  
	}  
	int count = mappedInterceptors.size();  
	return (count > 0 ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null);  
}  

AbstractHandlerMapping提供了进行拦截器初始化的操作。

总结

1. AbstractHandlerMapping提供了抽象方法getHandlerInternal在子类中实现,根据获得的Handler及配置的拦截器Interceptor来生成HandlerExecutionChain。
2. AbstractHandlerMapping已经实现了拦截器的初始化,所以子类的主要任务是实现模板方法getHandlerInternal来查找对应的Handler。
3. AbstractHandlerMapping采用模板模式设计了HandlerMapping实现的整体结构,子类只需要提供一些初始值或者具体的算法即可。

版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。