1.概念
跟请求处理有关的三个概念
Handlder: 处理器,直接对应的是Spring MVC的Controller层,它的具体表现形式有很多,
可以是类,也可以是方法,也可以是别的表现形式。标注了@RequestMapping的所有方法都可以看成是一个HandlerHandlerMapping:用来查找Handler,在Spring MVC中会处理很多请求,每个请求都需要一
个Handler来处理。HandlerAdapter:因为Spring MVC中的Handler可以是任意的形式,只要能处理请求就可
以,但是Servlet需要处理方法的结构是固定的,都是以request和response为参数的方法,
所以,需要一个适配器来用固定结构的Servlet处理方法调用灵活的Handler来进行处理。
2.HandlerMapping
HandlerMapping的作用是根据request找到相应的处理器Handler和Interceptor,HandlerMapping的接口只有一个方法
//方法的实现非常简单,通过request参数返回HandlerExecutionChain
HandlerExecutionChain getHandler(HttpServletRequest var1) throws Exception;
DispatcherServlet中查找getHandler的实现
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//查找Handler是通过迭代器来遍历所有的HandlerMapping,当找到一个
HandlerExecutionChain,就立即返回
Iterator var2 = this.handlerMappings.iterator();
HandlerExecutionChain handler;
do {
if(!var2.hasNext()) {
return null;
}
HandlerMapping hm = (HandlerMapping)var2.next();
if(this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name \'" + this.getServletName() + "\'");
}
//当handler不为空时,调出循环,返回handler
handler = hm.getHandler(request);
} while(handler == null);
return handler;
}
2.1.AbstractHandlerMapping
AbstractHandlerMapping是HandlerMapping的抽象实现,所有HandlerMapping都继承自AbstractHandlerMapping。AbstractHandlerMapping采用模板模式设计了HandlerMapping实现的整体结构,子类只需要通过模板方法提供一些具体的实现就行了。
2.1.1 AbstractHandlerMapping初始化
AbstractHandlerMapping的创建就是在initApplicationContext方法里面实现的
protected void initApplicationContext() throws BeansException {
//用于给子类提供一个添加(或修改)Interceptors的入口
this.extendInterceptors(this.interceptors);
this.detectMappedInterceptors(this.mappedInterceptors);
this.initInterceptors();
}
//detectMappedInterceptors方法将SpringMVC容器及父容器中的所有
MappedInterceptor类型的Bean添加到mappedInterceptors属性
protected void detectMappedInterceptors(List<MappedInterceptor> mappedInterceptors) {
mappedInterceptors.addAll(BeanFactoryUtils.beansOfTypeIncludingAncestors(this.getApplicationContext(), MappedInterceptor.class, true, false).values());
}
//initInterceptors方法作用是初始化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");
}
if(interceptor instanceof MappedInterceptor) {
this.mappedInterceptors.add((MappedInterceptor)interceptor);
} else {
this.adaptedInterceptors.add(this.adaptInterceptor(interceptor));
}
}
}
}
AbstractHandlerMapping中的Interceptor有三个List类型的属性:interceptors、mappedInterceptors和adaptedInterceptors
Interceptors: 用于配置SpringMVC的拦截器,有两种设置方式:1、注册HandlerMa-
pping时通过属性设置;2、通过子类的extendInterceptors钩子方法进行设置。Interceptors并不会直接使用,而是通过initInterceptors方法按类型分配到mappedInterceptors和adaptedInterceptors中进行使用,Interceptors只用于配置。mappedInterceptors:此类Interceptors在使用时需要与请求的url进行匹配,只有匹配成功后才会添加到getHandler的返回值HandlerExecutionChain里。它有两种获取途径:从interceptors获取或者注册到spring的容器中通过detectMappedInterceptors方法获取
adaptedInterceptors: 这种类型的Interceptors不需要进行匹配,在getHandler中
会全部添加到返回值HandlerExecutionChain里面。它只能从interceptors中获取。
2.1.2.AbstractHandlerMapping的用途
HandlerMapping是通过getHandler方法来获取处理器Handler和拦截器Interceptor的
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//获取handler,getHandlerInternal是模板方法,主要由子类来实现
Object handler = this.getHandlerInternal(request);
//使用默认的Handler,默认的Handler保存在AbstractHandlerMapping的一个Object类型的属性defaultHandler中,可以在配置HandlerMapping时进行配置,也可以在子类中进行设置
if(handler == null) {
handler = this.getDefaultHandler();
}
if(handler == null) {
return null;
} else {
//如果找到的Handler是String类型,则以它为名到Spring MVC的容器里查找相应的Bean
if(handler instanceof String) {
String handlerName = (String)handler;
handler = this.getApplicationContext().getBean(handlerName);
}
return this.getHandlerExecutionChain(handler, request);
}
}
//查找HandlerExecutionChain的方法
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//创建HandlerExecutionChain类型的变量
HandlerExecutionChain chain = handler instanceof HandlerExecutionChain?(HandlerExecutionChain)handler:new HandlerExecutionChain(handler);
//然后将符合类型的adaptedInterceptors和mappedInterceptor添加到HandlerExecutionChain
chain.addInterceptors(this.getAdaptedInterceptors());
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
Iterator var5 = this.mappedInterceptors.iterator();
while(var5.hasNext()) {
MappedInterceptor mappedInterceptor = (MappedInterceptor)var5.next();
if(mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
return chain;
}
2.1.3.Map(保存url和Handler)初始化
afterPropertiesSet方法是bean初始化完成之后,执行的方法,要求bean要实现InitializingBean接口
public void afterPropertiesSet() {
this.initHandlerMethods();
}
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
HandlerMethod newHandlerMethod = this.createHandlerMethod(handler, method);
HandlerMethod oldHandlerMethod = (HandlerMethod)this.handlerMethods.get(mapping);
if(oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {
throw new IllegalStateException("Ambiguous mapping found. Cannot map \'" + newHandlerMethod.getBean() + "\' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already \'" + oldHandlerMethod.getBean() + "\' bean method\n" + oldHandlerMethod + " mapped.");
} else {
this.handlerMethods.put(mapping, newHandlerMethod);
if(this.logger.isInfoEnabled()) {
this.logger.info("Mapped \"" + mapping + "\" onto " + newHandlerMethod);
}
Set patterns = this.getMappingPathPatterns(mapping);
Iterator name = patterns.iterator();
while(name.hasNext()) {
String pattern = (String)name.next();
if(!this.getPathMatcher().isPattern(pattern)) {
this.urlMap.add(pattern, mapping);
}
}
if(this.namingStrategy != null) {
String name1 = this.namingStrategy.getName(newHandlerMethod, mapping);
this.updateNameMap(name1, newHandlerMethod);
}
}
}
request请求中的url部门包括方法的@RequestMapping的和类的@RequestMapping注解,类中的注解会在下面的方法中做处理
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo info = null;
RequestMapping methodAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(method, RequestMapping.class);
if(methodAnnotation != null) {
//判断方法上面是否有注解
RequestCondition methodCondition = this.getCustomMethodCondition(method);
info = this.createRequestMappingInfo(methodAnnotation, methodCondition);
//判读类上面是否有注解,如果有则将类上面的注解和方法上面的注解做combine处理
RequestMapping typeAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
if(typeAnnotation != null) {
RequestCondition typeCondition = this.getCustomTypeCondition(handlerType);
info = this.createRequestMappingInfo(typeAnnotation, typeCondition).combine(info);
}
}
return info;
}