SpringMVC 源码剖析
0 从源码角度分析SpringMVC执行流程
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch ( HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = getHandler ( request) ;
HandlerAdapter ha = getHandlerAdapter ( mappedHandler. getHandler ( ) ) ;
if ( ! mappedHandler. applyPreHandle ( processedRequest, response) ) {
return ;
}
mv = ha. handle ( processedRequest, response, mappedHandler. getHandler ( ) ) ;
mappedHandler. applyPostHandle ( processedRequest, response, mv) ;
processDispatchResult ( processedRequest, response, mappedHandler, mv, dispatchException) ;
}
private void processDispatchResult ( HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
render ( mv, request, response) ;
mappedHandler. triggerAfterCompletion ( request, response, null ) ;
}
protected void render ( ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
View view = resolveViewName ( viewName, mv. getModelInternal ( ) , locale, request) ;
view. render ( mv. getModelInternal ( ) , request, response) ;
}
protected View resolveViewName ( String viewName, @Nullable Map < String , Object > model,
Locale locale, HttpServletRequest request) throws Exception {
ViewResolver viewResolver;
View view = viewResolver. resolveViewName ( viewName, locale) ;
}
}
public interface ViewResolver {
View resolveViewName ( String viewName, Locale locale) throws Exception ;
}
public interface View {
void render ( @Nullable Map < String , ? > model, HttpServletRequest request, HttpServletResponse response)
throws Exception ;
}
1 关于根据请求获取处理器执行链
分析这一行代码:
HandlerExecutionChain mappedHandler = getHandler ( request) ;
1. HandlerExecutionChain :处理器执行链对象
2. HandlerExecutionChain 中的属性:
public class HandlerExecutionChain {
Object handler = new HandlerMethod ( . . . . . ) ;
List < HandlerInterceptor > interceptorList;
}
3. HandlerMethod 是什么?
HandlerMethod 是最核心的要执行的目标,翻译为:处理器方法。
注意:HandlerMethod 是在web服务器启动时初始化spring容器的时候,就创建好了。
这个类当中比较重要的属性包括:beanName和Method
例如,以下代码:
@Controller ( "userController" )
public class UserController {
@RequestMapping ( "/login" )
public String login ( User user) {
return . . . .
}
}
那么以上代码对应了一个HandlerMethod 对象:
public class HandlerMethod {
private String beanName = "userController" ;
private Method loginMethod;
}
4. getHandler ( request) ;
这个方法还是在DispatcherServlet 类中。
protected HandlerExecutionChain getHandler ( HttpServletRequest request) throws Exception {
if ( this . handlerMappings != null ) {
for ( HandlerMapping mapping : this . handlerMappings) {
HandlerExecutionChain handler = mapping. getHandler ( request) ;
if ( handler != null ) {
return handler;
}
}
}
return null ;
}
重点:
我们处理请求的第一步代码是:HandlerExecutionChain mappedHandler = getHandler ( request) ;
其本质上是调用了:HandlerExecutionChain handler = mapping. getHandler ( request) ;
mapping变量就是 HandlerMapping 。
HandlerMapping 是一个接口:
翻译为处理器映射器,专门负责映射的。就是本质上根据请求路径去映射处理器方法的。
HandlerMapping 接口下有很多实现类:
例如其中一个比较有名的,常用的:RequestMappingHandlerMapping
这个 RequestMappingHandlerMapping 叫做:@RequestMapping 注解专用的处理器映射器对象。
当然,如果你没有使用 @RequestMapping 注解,也可以写xml配置文件来进行映射,那个时候对应的就是其他的HandlerMapping 接口的实现类了。
HandlerMapping 对象也是在服务器启动阶段创建的,所有的HandlerMapping 对象都是在服务器启动阶段创建,并且存放到集合中。
public class DispatcherServlet {
List < HandlerMapping > handlerMappings;
}
5. RequestMappingHandlerMapping 中的 getHandler ( request) ;
HandlerExecutionChain handler = mapping. getHandler ( request) ;
mapping. getHandler ( request) ; 这个方法底层一定是获取了 HandlerMethod 对象,将其赋值给 HandlerExecutionChain 的handler属性
public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping {
protected void registerHandlerMethod ( Object handler, Method method, RequestMappingInfo mapping) {
super . registerHandlerMethod ( handler, method, mapping) ;
updateConsumesCondition ( mapping, method) ;
}
}
public class AbstractHandlerMethodMapping {
protected void registerHandlerMethod ( Object handler, Method method, T mapping) {
this . mappingRegistry. register ( mapping, handler, method) ;
}
public void register ( T mapping, Object handler, Method method) {
HandlerMethod handlerMethod = createHandlerMethod ( handler, method) ;
}
protected HandlerMethod createHandlerMethod ( Object handler, Method method) {
if ( handler instanceof String beanName) {
return new HandlerMethod ( beanName,
obtainApplicationContext ( ) . getAutowireCapableBeanFactory ( ) ,
obtainApplicationContext ( ) ,
method) ;
}
return new HandlerMethod ( handler, method) ;
}
}
这一步牵连到的类有哪些:
HandlerExecutionChain
HandlerMethod
HandlerInterceptor
HandlerMapping
RequestMappingHandlerMapping (是HandlerMaping 接口的实现)
2 关于根据处理器来获取处理器适配器
分析:
HandlerAdapter ha = getHandlerAdapter ( mappedHandler. getHandler ( ) ) ;
1. 底层使用了适配器模式。
2. 每一个处理器( 我们自己写的Controller ) ,都有自己适合的处理器适配器。
3. 在SpringMVC 当中处理器适配器也有很多种,其中一个比较有名的,常用的处理器适配器是:RequestMappingHandlerAdapter
这个处理器适配器是专门处理 “处理器方法”上有 @RequestMapping 注解的。
4. mappedHandler. getHandler ( ) 获取的是 HandlerMethod 对象
5. HandlerAdapter 也是一个接口:
其中有一个常用的实现类:RequestMappingHandlerAdapter
6. 在服务器启动阶段,所有的 HandlerAdapter 接口的实现类都会创建出来。在服务器启动阶段!!!!!!
List < HandlerAdapter > handlerAdapters;
7. HandlerAdapter 接口非常重要,通过这个接口来调用最终的 HandlerMethod 。
8. HandlerAdapter 是适配器,是对 HandlerMethod 进行的适配。
9. 在DispatcherServlet 类中,如下代码:
protected HandlerAdapter getHandlerAdapter ( Object handler) throws ServletException {
if ( this . handlerAdapters != null ) {
for ( HandlerAdapter adapter : this . handlerAdapters) {
if ( adapter. supports ( handler) ) {
return adapter;
}
}
}
}
3 关于执行请求对应的拦截器preHandle
关于执行请求对应的拦截器的preHandle方法
DispatcherServlet :
if ( ! mappedHandler. applyPreHandle ( processedRequest, response) ) {
return ;
}
HandlerExecutionChain :
boolean applyPreHandle ( HttpServletRequest request, HttpServletResponse response) throws Exception {
for ( int i = 0 ; i < this . interceptorList. size ( ) ; i++ ) {
HandlerInterceptor interceptor = this . interceptorList. get ( i) ;
if ( ! interceptor. preHandle ( request, response, this . handler) ) {
triggerAfterCompletion ( request, response, null ) ;
return false ;
}
this . interceptorIndex = i;
}
return true ;
}
遍历List 集合,从List 集合中取出每一个 HandlerInterceptor 对象,调用 preHandle,i++ ,可见是顺序调用。
4 关于调用处理器方法
关于调用处理器方法:
mv = ha. handle ( processedRequest, response, mappedHandler. getHandler ( ) ) ;
ha 是处理器适配器
mv 是ModelAndView 对象
这个方法是最核心的,调用请求路径对应的HandlerMethod 。(调用处理器方法。)
ha是HandlerAdapter ,如果是 @RequestMapping 注解对应的,那么就是 RequestMappingHandlerAdapter :
RequestMappingHandlerAdapter :
protected ModelAndView handleInternal ( HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
mav = invokeHandlerMethod ( request, response, handlerMethod) ;
}
protected ModelAndView invokeHandlerMethod ( HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
WebDataBinderFactory binderFactory = getDataBinderFactory ( handlerMethod) ;
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod ( handlerMethod) ;
invocableMethod. setDataBinderFactory ( binderFactory) ;
invocableMethod. setParameterNameDiscoverer ( this . parameterNameDiscoverer) ;
invocableMethod. invokeAndHandle ( webRequest, mavContainer) ;
}
在HandlerAdapter 中做的核心事情:
将前端提交的form数据通过 HttpMessageConverter 将其转换成 POJO 对象。(数据转换)
并将数据绑定到 HandlerMethod 对象上。
调用HandlerMethod 。
返回 ModelAndView
5 关于执行请求对应的拦截器的postHandle
DispatcherServlet :
mappedHandler. applyPostHandle ( processedRequest, response, mv) ;
HandlerExecutionChain :
void applyPostHandle ( HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
for ( int i = this . interceptorList. size ( ) - 1 ; i >= 0 ; i-- ) {
HandlerInterceptor interceptor = this . interceptorList. get ( i) ;
interceptor. postHandle ( request, response, this . handler, mv) ;
}
}
通过源码解决,可以很轻松的看到,从List 集合中逆序( i-- ) 逐一取出拦截器对象,并且调用拦截器的 postHandle方法。
6 关于处理分发结果
public class DispatcherServlet {
processDispatchResult ( processedRequest, response, mappedHandler, mv, dispatchException) ;
private void processDispatchResult ( HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
render ( mv, request, response) ;
}
protected void render ( ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
View view = resolveViewName ( viewName, mv. getModelInternal ( ) , locale, request) ;
view. render ( mv. getModelInternal ( ) , request, response) ;
}
protected View resolveViewName ( String viewName, @Nullable Map < String , Object > model,
Locale locale, HttpServletRequest request) throws Exception {
ViewResolver viewResolver;
View view = viewResolver. resolveViewName ( viewName, locale) ;
}
}
public interface ViewResolver {
View resolveViewName ( String viewName, Locale locale) throws Exception ;
}
public interface View {
void render ( @Nullable Map < String , ? > model, HttpServletRequest request, HttpServletResponse response)
throws Exception ;
}
7 关于执行拦截器的afterCompletion方法
DispatcherServlet :
private void processDispatchResult ( HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
render ( mv, request, response) ;
mappedHandler. triggerAfterCompletion ( request, response, null ) ;
}
HandlerExecutionChain :
void triggerAfterCompletion ( HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
for ( int i = this . interceptorIndex; i >= 0 ; i-- ) {
HandlerInterceptor interceptor = this . interceptorList. get ( i) ;
try {
interceptor. afterCompletion ( request, response, this . handler, ex) ;
}
catch ( Throwable ex2) {
logger. error ( "HandlerInterceptor.afterCompletion threw exception" , ex2) ;
}
}
}
通过源码可以看出,也是通过逆序( i-- ) 的方式进行拦截器的调用,调用拦截器的afterCompletion方法。