SSM-SpringMVC-04:SpringMVC深入浅出理解HandleMapping(源码刨析)

释放双眼,带上耳机,听听看~!

 

————吾亦无他,唯手熟尔,谦卑若愚,好学若饥————-

 

 

先从概念理解,从中央调度器,携带参数request,调度到HandleMapping处理器映射器,处理器映射器返回处理器执行链给中央调度器

 

我从底层走一遍,印证这个概念:

1.都说是中央调度器的,所以先找到中央调度器DispatcherServlet

2.从他里面找到一个方法   ctrl+f 找(doDistch)

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
1    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
2        HttpServletRequest processedRequest = request;
3        HandlerExecutionChain mappedHandler = null;
4        boolean multipartRequestParsed = false;
5        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
6
7        try {
8            try {
9                ModelAndView err = null;
10                Exception dispatchException = null;
11
12                try {
13                    processedRequest = this.checkMultipart(request);
14                    multipartRequestParsed = processedRequest != request;
15                    mappedHandler = this.getHandler(processedRequest);
16                    if(mappedHandler == null || mappedHandler.getHandler() == null) {
17                        this.noHandlerFound(processedRequest, response);
18                        return;
19                    }
20
21                    HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());
22                    String method = request.getMethod();
23                    boolean isGet = "GET".equals(method);
24                    if(isGet || "HEAD".equals(method)) {
25                        long lastModified = ex.getLastModified(request, mappedHandler.getHandler());
26                        if(this.logger.isDebugEnabled()) {
27                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
28                        }
29
30                        if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
31                            return;
32                        }
33                    }
34
35                    if(!mappedHandler.applyPreHandle(processedRequest, response)) {
36                        return;
37                    }
38
39                    err = ex.handle(processedRequest, response, mappedHandler.getHandler());
40                    if(asyncManager.isConcurrentHandlingStarted()) {
41                        return;
42                    }
43
44                    this.applyDefaultViewName(processedRequest, err);
45                    mappedHandler.applyPostHandle(processedRequest, response, err);
46                } catch (Exception var19) {
47                    dispatchException = var19;
48                }
49
50                this.processDispatchResult(processedRequest, response, mappedHandler, err, dispatchException);
51            } catch (Exception var20) {
52                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
53            } catch (Error var21) {
54                this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
55            }
56
57        } finally {
58            if(asyncManager.isConcurrentHandlingStarted()) {
59                if(mappedHandler != null) {
60                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
61                }
62            } else if(multipartRequestParsed) {
63                this.cleanupMultipart(processedRequest);
64            }
65
66        }
67    }
68

 

这个方法里面很多内容不需要关注,需要关注的的我讲讲


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1        HttpServletRequest processedRequest = request;
2        //接收请求
3        HandlerExecutionChain mappedHandler = null;
4        //处理器执行链
5        boolean multipartRequestParsed = false;
6        //多部分请求,文件上传
7        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
8        //异部请求
9
10        try {
11            try {
12              
13                ModelAndView err = null;
14                 //视图解析
15
16                try {
17                    
18                    processedRequest = this.checkMultipart(request);
19                    //检查是否是多部分请求
20                    multipartRequestParsed = processedRequest != request;
21                    
22                    mappedHandler = this.getHandler(processedRequest);  
23                     //这就返回处理器执行链
24

3.到这儿,点击getHandler(processedRequest)查看


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
2        Iterator var2 = this.handlerMappings.iterator();
3
4        HandlerExecutionChain handler;
5        do {
6            if(!var2.hasNext()) {
7                return null;
8            }
9
10            HandlerMapping hm = (HandlerMapping)var2.next();
11            if(this.logger.isTraceEnabled()) {
12                this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name \'" + this.getServletName() + "\'");
13            }
14
15            handler = hm.getHandler(request);
16        } while(handler == null);
17
18        return handler;
19    }
20

我把关键代码提炼出来解释一波


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1        //迭代器,没做泛型,handlerMapping是list集合
2        Iterator var2 = this.handlerMappings.iterator();
3        //处理器执行链
4        HandlerExecutionChain handler;
5        do {
6            if(!var2.hasNext()) {
7                return null;
8            }
9            //处理器映射器
10            HandlerMapping hm = (HandlerMapping)var2.next();
11          
12            //继续追踪
13            handler = hm.getHandler(request);
14        } while(handler == null);
15
16        return handler;    
17

**4.追踪hm.getHandler(request)方法,发现他是HandlerMapping接口的,(Ctrl+H)找它的实现类AbstractHandlerMapping,ctrl+F找getHandler
**


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
2        Object handler = this.getHandlerInternal(request);
3        if(handler == null) {
4            handler = this.getDefaultHandler();
5        }
6
7        if(handler == null) {
8            return null;
9        } else {
10            if(handler instanceof String) {
11                String executionChain = (String)handler;
12                handler = this.getApplicationContext().getBean(executionChain);
13            }
14
15            HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);
16            if(CorsUtils.isCorsRequest(request)) {
17                CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
18                CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
19                CorsConfiguration config = globalConfig != null?globalConfig.combine(handlerConfig):handlerConfig;
20                executionChain1 = this.getCorsHandlerExecutionChain(request, executionChain1, config);
21            }
22
23            return executionChain1;
24        }
25    }
26

同样,我把关键代码提出来解释一波


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1//获取处理器
2        Object handler = this.getHandlerInternal(request);
3        //处理器为空就用默认的
4        if(handler == null) {
5            handler = this.getDefaultHandler();
6        }
7        //默认的也是空就返回null
8        if(handler == null) {
9            return null;
10        } else {
11            //判断是否是String类型
12            if(handler instanceof String) {
13                //这儿就是我们一般用的处理器的从配置文件bean的id
14                String handlerName = (String)handler;  //  /hello
15                //这就是Spring啊
16                handler = this.getApplicationContext().getBean(handlerName);
17            }  
18        //获取处理程序执行链
19

1
2
1        HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);
2

1
2
3
4
1//返回的时候变成携带处理器的了  
2    
3return this.getHandlerExecutionChain(handler, request); }
4

5.追踪获取程序执行链,this.getHandlerExecutionChain(handler,request)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
2        //三元表达式,是处理器执行链就强转,不是就获取根据处理器生成一个
3        HandlerExecutionChain chain = handler instanceof HandlerExecutionChain?(HandlerExecutionChain)handler:new HandlerExecutionChain(handler);
4        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
5        Iterator var5 = this.adaptedInterceptors.iterator();
6
7        while(var5.hasNext()) {
8
9            //只需要知道这儿添加拦截器即可
10            HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();
11            if(interceptor instanceof MappedInterceptor) {
12                MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
13                if(mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
14                    chain.addInterceptor(mappedInterceptor.getInterceptor());
15                }
16            } else {
17                chain.addInterceptor(interceptor);
18            }
19        }
20
21        return chain;
22    }
23

 

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C++回调函数

2022-1-11 12:36:11

安全资讯

诺基亚表示已对苹果提起新一轮专利诉讼

2016-12-22 15:42:50

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索