springmvc 的请求处理过程(精编) springmvc 的请求处理过程(精编)

springmvc 的请求处理过程(精编)

 

 

1. DispacherServlet 前端控制器接受发送过来的请求,交给HandlerMapping 处理映射器,

2. HandlerMapping 处理映射器, 根据请求找到相应的HandlerAdapter 处理适配器(处理适配器就是那些拦截器活着吧Controller)

3. HandlerAdapter处理器适配器,处理一些功能请求, 返回一个ModleAndView 对象,包括模型数据、逻辑视图名。

ViewResolver视图解析器 ,先根据ModleAndView 中设置的view 解析具体视图

5. 然后将Modle模型中得数据渲染到View中。

这些过程都是以DispatchServlet 为中轴线进行的。

 

首先说说:HandlerMapping 视图解析器的接口

作用是根据当前请求的找到对应的Handler 并将Handler(执行程序) 与一对HandlerInterceptor(拦截器)封装到HandlerExecutionChain 对象中。在HandlerMapping接口的内部只有一个方法,如下

  • HandlerExecutionChain getHandler(HttpServletRequest request);

HandlerMapping 是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler,而 HandlerMapping 具体有哪些实现类下面就会详细分析。

 

 HandlerMapping 实现类有两个分支,分别继承自 AbstractHandlerMethodMapping(得到 HandlerMethod)和 AbstractUrlHandlerMapping(得到 HttpRequestHandler、Controller 或 Servlet),它们又统一继承于AbstractHandlerMapping

 

 

先来看一下 AbstractHandlerMapping,它实现了 HandlerMapping 接口中的 getHandler() 方法,源码如下所示:

@Override

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

// 根据请求获取执行程序,具体的获取方式由子类决定,getHandlerInternal() 是抽象方法

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);

}

// 将 Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

return getHandlerExecutionChain(handler, request);

}

//  Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

 

可以看到在这个方法中又调用了 getHandlerInternal() 方法获取到了 Handler 对象,而 Handler 对象具体内容是由它的子类去定义的。下面就来一看下 AbstractHandlerMapping 的两个分支子类。

 

2):AbstractHandlerMethodMapping

AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是 HandlerMethod,即这个 Handler 是一个方法,它保存了方法的信息(如Method),这样一个 Controller 就可以处理多个请求了,源码如下所示:

 

@Override

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {

// 根据当前请求获取“查找路径” 从 HttpServletRequest中获取请求的路径。

String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);

// 获取当前请求最佳匹配的处理方法(即Controller类的方法中)(获取请求中的方法)

HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);

}

 

 

 

下面的是 lookupHandlerMethod(lookupPath, request); 的方法体:

@Nullable

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {

List<AbstractHandlerMethodMapping<T>.Match> matches = new ArrayList();

//根据请的路径找到 直接访问的路径。

List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);

if (directPathMatches != null) {

this.addMatchingMappings(directPathMatches, matches, request);

}

 

if (matches.isEmpty()) {

this.addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);

}

 

if (!matches.isEmpty()) {

Comparator<AbstractHandlerMethodMapping<T>.Match> comparator = new AbstractHandlerMethodMapping.MatchComparator(this.getMappingComparator(request));

Collections.sort(matches, comparator);

if (this.logger.isTraceEnabled()) {

this.logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches);

}

 

AbstractHandlerMethodMapping<T>.Match bestMatch = (AbstractHandlerMethodMapping.Match)matches.get(0);

if (matches.size() > 1) {

if (CorsUtils.isPreFlightRequest(request)) {

return PREFLIGHT_AMBIGUOUS_MATCH;

}

 

AbstractHandlerMethodMapping<T>.Match secondBestMatch = (AbstractHandlerMethodMapping.Match)matches.get(1);

if (comparator.compare(bestMatch, secondBestMatch) == 0) {

Method m1 = bestMatch.handlerMethod.getMethod();

Method m2 = secondBestMatch.handlerMethod.getMethod();

throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" + request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");

}

}

 

this.handleMatch(bestMatch.mapping, lookupPath, request);

return bestMatch.handlerMethod;

else {

return this.handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);

}

}

上述代码中 lookupHandlerMethod() 方法主要工作是在 Map<T, HandlerMethod> handlerMethods 中找到 HandlerMethod,这里的 T 是 HandlerMappingInfo,它封装了 @RequestMapping 注解中的信息。那 HandlerMethod 是怎么创建的(即怎么把 Controller 的方法变成了它),

即: mapping 与handlerMethod(处理方法的)关系;

继续看一下源码找到 initHandlerMethods() 方法,这个方法是在这个类创建后调用的,如下所示是它的源码:

 

protected void initHandlerMethods() {

// 从容器中获取所有 Bean 的名称,detectHandlerMethodsInAncestorContexts 默认false,不从父容器中查找

//即默认只查找 SpringMVC 的 IOC 容器,不查找它的父容器 Spring 的 IOC 容器

String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :

getApplicationContext().getBeanNamesForType(Object.class));

for (String beanName : beanNames) {

// 这里的 isHandler()方法由子类实现,判断是否拥有 @Controller 注解或 @RequestMapping 注解

if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(beanName))){

// 利用反射得到 Bean 中的 Method 并包装成 HandlerMethod,然后放入 Map 中

detectHandlerMethods(beanName);

}

}

handlerMethodsInitialized(getHandlerMethods());

}

看完上述代码后,可以知道是在 detectHandlerMethods() 方法中将 Bean 的方法转换为 HandlerMethod 对象,具体实现如下

 

protected void detectHandlerMethods(final Object handler) {

// 获取这个 Bean 的 Class 对象

Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());

// 避免重复调用 getMappingForMethod(),getMappingForMethod() 将重新构建 RequestMappingInfo 实例

final Map<Method, T> mappings = new IdentityHashMap<Method, T>();

// 获取被代理前的原始类型

final Class<?> userType = ClassUtils.getUserClass(handlerType);

// 获取 Method

Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {

@Override

public boolean matches(Method method) {

// 根据 Method 和它的 @RequestMapping 注解,创建 RequestMappingInfo 对象。

// 这里的 T 就是 RequestMappingInfo,它封装了 @RequestMapping 信息

T mapping = getMappingForMethod(method, userType);

if (mapping != null) {

mappings.put(method, mapping);

return true;

} else {

return false;

}

}

});

for (Method method : methods) {

// 注册 Method 和它的映射,RequestMappingInfo 储存着映射信息

registerHandlerMethod(handler, method, mappings.get(method));

}

}

 

最后在 registerHandlerMethod() 方法中,将 RequestMappingInfo 作为 key,把 Method 包装成HandlerMethod 作为 value 添加到了 Map<T, HandlerMethod> handlerMethods 中。

 

protected void registerHandlerMethod(Object handler, Method method, T mapping) {

HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);

HandlerMethod oldHandlerMethod = this.handlerMethods.get(mapping);

if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {

throw new IllegalStateException("");

}

this.handlerMethods.put(mapping, newHandlerMethod);

Set<String> patterns = getMappingPathPatterns(mapping);

for (String pattern : patterns) {

if (!getPathMatcher().isPattern(pattern)) {

this.urlMap.add(pattern, mapping);

}

}

}

 

 

接下来我们接着看看:HandlerAdapter

根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象。HandlerAdapter 接口中的方法如下:

 

HandlerAdapter的接口的方法:

public interface HandlerAdapter {

boolean supports(Object var1);

ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

 

long getLastModified(HttpServletRequest var1, Object var2);

}

 

该接口的具体的实现类有:

HttpRequestHandlerAdapterSimpleControllerHandlerAdapterAnnotationMethodHandlerAdapter,这个三个类是具体实现HandlerAdapter这个接口的三个类;

1 RequestMappingHandlerAdapter

从上面的文章中可以知道,利用 RequestMappingHandlerMapping 获取的 Handler 是 HadnlerMethod 类型,它代表 Controller 里要执行的方法,而 RequestMappingHandlerAdapter 可以执行 HadnlerMethod 对象。

RequestMappingHandlerAdapter 的 handle()方法是在它的父类 AbstractHandlerMethodAdapter 类中实现的,源码如下所示

 

@Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }

 

handleInternal() 方法是由 RequestMappingHandlerAdapter 自己来实现的,源码如下所示

 

@Override

protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

// 是否通过 @SessionAttributes 注释声明了 session 属性。

if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {

checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);

} else {

checkAndPrepare(request, response, true);

}

// 是否需要在 synchronize 块中执行

if (this.synchronizeOnSession) {

HttpSession session = request.getSession(false);

if (session != null) {

Object mutex = WebUtils.getSessionMutex(session);

synchronized (mutex) {

// 执行 HandlerMethod

return invokeHandleMethod(request, response, handlerMethod);

}

}

}

// 执行 HandlerMethod,得到 ModelAndView

return invokeHandleMethod(request, response, handlerMethod);

}

 

继续再来看一下如何得到 ModelAndViewinvokeHandlerMethod() 方法如下

 

private ModelAndView invokeHandleMethod(HttpServletRequest request,

HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

//

ServletWebRequest webRequest = new ServletWebRequest(request, response);

// 数据绑定

WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);

ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// 绑定参数,执行方法

ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);

// 创建模型和视图容器

ModelAndViewContainer mavContainer = new ModelAndViewContainer();

// 设置FlasgMap中的值

mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));

// 初始化模型

modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);

mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

 

AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);

asyncWebRequest.setTimeout(this.asyncRequestTimeout);

 

final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

asyncManager.setTaskExecutor(this.taskExecutor);

asyncManager.setAsyncWebRequest(asyncWebRequest);

asyncManager.registerCallableInterceptors(this.callableInterceptors);

asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

if (asyncManager.hasConcurrentResult()) {

Object result = asyncManager.getConcurrentResult();

mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];

asyncManager.clearConcurrentResult();

requestMappingMethod = requestMappingMethod.wrapConcurrentResult(result);

}

requestMappingMethod.invokeAndHandle(webRequest, mavContainer);

if (asyncManager.isConcurrentHandlingStarted()) {

return null;

}

return getModelAndView(mavContainer, modelFactory, webRequest);

}

 

 

2 HttpRequestHandlerAdapter

HttpRequestHandlerAdapter 可以执行 HttpRequestHandler 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; }

 

3 SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter 可以执行 Controller 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }

 

4 SimpleServletHandlerAdapter 

SimpleServletHandlerAdapter 可以执行 Servlet 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((Servlet) handler).service(request, response); return null; }

 

ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex); 

 

 

1. DispacherServlet 前端控制器接受发送过来的请求,交给HandlerMapping 处理映射器,

2. HandlerMapping 处理映射器, 根据请求找到相应的HandlerAdapter 处理适配器(处理适配器就是那些拦截器活着吧Controller)

3. HandlerAdapter处理器适配器,处理一些功能请求, 返回一个ModleAndView 对象,包括模型数据、逻辑视图名。

ViewResolver视图解析器 ,先根据ModleAndView 中设置的view 解析具体视图

5. 然后将Modle模型中得数据渲染到View中。

这些过程都是以DispatchServlet 为中轴线进行的。

 

首先说说:HandlerMapping 视图解析器的接口

作用是根据当前请求的找到对应的Handler 并将Handler(执行程序) 与一对HandlerInterceptor(拦截器)封装到HandlerExecutionChain 对象中。在HandlerMapping接口的内部只有一个方法,如下

  • HandlerExecutionChain getHandler(HttpServletRequest request);

HandlerMapping 是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler,而 HandlerMapping 具体有哪些实现类下面就会详细分析。

 

 HandlerMapping 实现类有两个分支,分别继承自 AbstractHandlerMethodMapping(得到 HandlerMethod)和 AbstractUrlHandlerMapping(得到 HttpRequestHandler、Controller 或 Servlet),它们又统一继承于AbstractHandlerMapping

 

 

先来看一下 AbstractHandlerMapping,它实现了 HandlerMapping 接口中的 getHandler() 方法,源码如下所示:

@Override

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

// 根据请求获取执行程序,具体的获取方式由子类决定,getHandlerInternal() 是抽象方法

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);

}

// 将 Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

return getHandlerExecutionChain(handler, request);

}

//  Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

 

可以看到在这个方法中又调用了 getHandlerInternal() 方法获取到了 Handler 对象,而 Handler 对象具体内容是由它的子类去定义的。下面就来一看下 AbstractHandlerMapping 的两个分支子类。

 

2):AbstractHandlerMethodMapping

AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是 HandlerMethod,即这个 Handler 是一个方法,它保存了方法的信息(如Method),这样一个 Controller 就可以处理多个请求了,源码如下所示:

 

@Override

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {

// 根据当前请求获取“查找路径” 从 HttpServletRequest中获取请求的路径。

String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);

// 获取当前请求最佳匹配的处理方法(即Controller类的方法中)(获取请求中的方法)

HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);

}

 

 

 

下面的是 lookupHandlerMethod(lookupPath, request); 的方法体:

@Nullable

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {

List<AbstractHandlerMethodMapping<T>.Match> matches = new ArrayList();

//根据请的路径找到 直接访问的路径。

List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);

if (directPathMatches != null) {

this.addMatchingMappings(directPathMatches, matches, request);

}

 

if (matches.isEmpty()) {

this.addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);

}

 

if (!matches.isEmpty()) {

Comparator<AbstractHandlerMethodMapping<T>.Match> comparator = new AbstractHandlerMethodMapping.MatchComparator(this.getMappingComparator(request));

Collections.sort(matches, comparator);

if (this.logger.isTraceEnabled()) {

this.logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches);

}

 

AbstractHandlerMethodMapping<T>.Match bestMatch = (AbstractHandlerMethodMapping.Match)matches.get(0);

if (matches.size() > 1) {

if (CorsUtils.isPreFlightRequest(request)) {

return PREFLIGHT_AMBIGUOUS_MATCH;

}

 

AbstractHandlerMethodMapping<T>.Match secondBestMatch = (AbstractHandlerMethodMapping.Match)matches.get(1);

if (comparator.compare(bestMatch, secondBestMatch) == 0) {

Method m1 = bestMatch.handlerMethod.getMethod();

Method m2 = secondBestMatch.handlerMethod.getMethod();

throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" + request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");

}

}

 

this.handleMatch(bestMatch.mapping, lookupPath, request);

return bestMatch.handlerMethod;

else {

return this.handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);

}

}

上述代码中 lookupHandlerMethod() 方法主要工作是在 Map<T, HandlerMethod> handlerMethods 中找到 HandlerMethod,这里的 T 是 HandlerMappingInfo,它封装了 @RequestMapping 注解中的信息。那 HandlerMethod 是怎么创建的(即怎么把 Controller 的方法变成了它),

即: mapping 与handlerMethod(处理方法的)关系;

继续看一下源码找到 initHandlerMethods() 方法,这个方法是在这个类创建后调用的,如下所示是它的源码:

 

protected void initHandlerMethods() {

// 从容器中获取所有 Bean 的名称,detectHandlerMethodsInAncestorContexts 默认false,不从父容器中查找

//即默认只查找 SpringMVC 的 IOC 容器,不查找它的父容器 Spring 的 IOC 容器

String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :

getApplicationContext().getBeanNamesForType(Object.class));

for (String beanName : beanNames) {

// 这里的 isHandler()方法由子类实现,判断是否拥有 @Controller 注解或 @RequestMapping 注解

if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(beanName))){

// 利用反射得到 Bean 中的 Method 并包装成 HandlerMethod,然后放入 Map 中

detectHandlerMethods(beanName);

}

}

handlerMethodsInitialized(getHandlerMethods());

}

看完上述代码后,可以知道是在 detectHandlerMethods() 方法中将 Bean 的方法转换为 HandlerMethod 对象,具体实现如下

 

protected void detectHandlerMethods(final Object handler) {

// 获取这个 Bean 的 Class 对象

Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());

// 避免重复调用 getMappingForMethod(),getMappingForMethod() 将重新构建 RequestMappingInfo 实例

final Map<Method, T> mappings = new IdentityHashMap<Method, T>();

// 获取被代理前的原始类型

final Class<?> userType = ClassUtils.getUserClass(handlerType);

// 获取 Method

Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {

@Override

public boolean matches(Method method) {

// 根据 Method 和它的 @RequestMapping 注解,创建 RequestMappingInfo 对象。

// 这里的 T 就是 RequestMappingInfo,它封装了 @RequestMapping 信息

T mapping = getMappingForMethod(method, userType);

if (mapping != null) {

mappings.put(method, mapping);

return true;

} else {

return false;

}

}

});

for (Method method : methods) {

// 注册 Method 和它的映射,RequestMappingInfo 储存着映射信息

registerHandlerMethod(handler, method, mappings.get(method));

}

}

 

最后在 registerHandlerMethod() 方法中,将 RequestMappingInfo 作为 key,把 Method 包装成HandlerMethod 作为 value 添加到了 Map<T, HandlerMethod> handlerMethods 中。

 

protected void registerHandlerMethod(Object handler, Method method, T mapping) {

HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);

HandlerMethod oldHandlerMethod = this.handlerMethods.get(mapping);

if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {

throw new IllegalStateException("");

}

this.handlerMethods.put(mapping, newHandlerMethod);

Set<String> patterns = getMappingPathPatterns(mapping);

for (String pattern : patterns) {

if (!getPathMatcher().isPattern(pattern)) {

this.urlMap.add(pattern, mapping);

}

}

}

 

 

接下来我们接着看看:HandlerAdapter

根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象。HandlerAdapter 接口中的方法如下:

 

HandlerAdapter的接口的方法:

public interface HandlerAdapter {

boolean supports(Object var1);

ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

 

long getLastModified(HttpServletRequest var1, Object var2);

}

 

该接口的具体的实现类有:

HttpRequestHandlerAdapterSimpleControllerHandlerAdapterAnnotationMethodHandlerAdapter,这个三个类是具体实现HandlerAdapter这个接口的三个类;

1 RequestMappingHandlerAdapter

从上面的文章中可以知道,利用 RequestMappingHandlerMapping 获取的 Handler 是 HadnlerMethod 类型,它代表 Controller 里要执行的方法,而 RequestMappingHandlerAdapter 可以执行 HadnlerMethod 对象。

RequestMappingHandlerAdapter 的 handle()方法是在它的父类 AbstractHandlerMethodAdapter 类中实现的,源码如下所示

 

@Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }

 

handleInternal() 方法是由 RequestMappingHandlerAdapter 自己来实现的,源码如下所示

 

@Override

protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

// 是否通过 @SessionAttributes 注释声明了 session 属性。

if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {

checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);

} else {

checkAndPrepare(request, response, true);

}

// 是否需要在 synchronize 块中执行

if (this.synchronizeOnSession) {

HttpSession session = request.getSession(false);

if (session != null) {

Object mutex = WebUtils.getSessionMutex(session);

synchronized (mutex) {

// 执行 HandlerMethod

return invokeHandleMethod(request, response, handlerMethod);

}

}

}

// 执行 HandlerMethod,得到 ModelAndView

return invokeHandleMethod(request, response, handlerMethod);

}

 

继续再来看一下如何得到 ModelAndViewinvokeHandlerMethod() 方法如下

 

private ModelAndView invokeHandleMethod(HttpServletRequest request,

HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

//

ServletWebRequest webRequest = new ServletWebRequest(request, response);

// 数据绑定

WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);

ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// 绑定参数,执行方法

ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);

// 创建模型和视图容器

ModelAndViewContainer mavContainer = new ModelAndViewContainer();

// 设置FlasgMap中的值

mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));

// 初始化模型

modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);

mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

 

AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);

asyncWebRequest.setTimeout(this.asyncRequestTimeout);

 

final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

asyncManager.setTaskExecutor(this.taskExecutor);

asyncManager.setAsyncWebRequest(asyncWebRequest);

asyncManager.registerCallableInterceptors(this.callableInterceptors);

asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

if (asyncManager.hasConcurrentResult()) {

Object result = asyncManager.getConcurrentResult();

mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];

asyncManager.clearConcurrentResult();

requestMappingMethod = requestMappingMethod.wrapConcurrentResult(result);

}

requestMappingMethod.invokeAndHandle(webRequest, mavContainer);

if (asyncManager.isConcurrentHandlingStarted()) {

return null;

}

return getModelAndView(mavContainer, modelFactory, webRequest);

}

 

 

2 HttpRequestHandlerAdapter

HttpRequestHandlerAdapter 可以执行 HttpRequestHandler 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; }

 

3 SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter 可以执行 Controller 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }

 

4 SimpleServletHandlerAdapter 

SimpleServletHandlerAdapter 可以执行 Servlet 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((Servlet) handler).service(request, response); return null; }

 

ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex); 

 

猜你喜欢

转载自www.cnblogs.com/wangdong811/p/10300247.html
今日推荐