@@ -417,7 +417,7 @@ initFlashMapManager方法会向容器注册SessionFlashMapManager对象,类图
417417
418418![ RequestMappingHandlerMapping类图] ( images/RequestMappingHandlerMapping.jpg )
419419
420- 初始化的入口位于AbstractHandlerMethodMapping的afterPropertiesSet方法 ,afterPropertiesSet调用了initHandlerMethods:
420+ 初始化的入口位于AbstractHandlerMethodMapping的afterPropertiesSet方法和AbstractHandlerMapping的initApplicationContext方法 ,afterPropertiesSet调用了initHandlerMethods:
421421
422422``` java
423423protected void initHandlerMethods() {
@@ -523,6 +523,21 @@ Cors的原理可以参考:
523523
524524而initCorsConfiguration方法的作用便是将@CrossOrigin 注解的各种属性封装在CorsConfiguration中。
525525
526+ #### 拦截器初始化
527+
528+ AbstractHandlerMapping.initApplicationContext:
529+
530+ ``` java
531+ @Override
532+ protected void initApplicationContext() throws BeansException {
533+ detectMappedInterceptors(this . adaptedInterceptors);
534+ }
535+ ```
536+
537+ 作用就是从容器中获取所有MappedInterceptor bean并放到adaptedInterceptors中,前面提到过了,我们使用mvc: interceptor 定义的拦截器其实就是MappedInterceptor对象。类图:
538+
539+ ![ MappedInterceptor类图] ( images/MappedInterceptor.jpg )
540+
526541## HandlerAdapter初始化
527542
528543同样,我们以RequestMappingHandlerAdapter为例进行说明,类图:
@@ -653,6 +668,7 @@ AbstractHandlerMapping.getHandler:
653668public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
654669 Object handler = getHandlerInternal(request);
655670 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
671+ // 判断请求头中是否有ORIGIN字段
656672 if (CorsUtils . isCorsRequest(request)) {
657673 CorsConfiguration globalConfig = this . corsConfigSource. getCorsConfiguration(request);
658674 CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
@@ -664,4 +680,65 @@ public final HandlerExecutionChain getHandler(HttpServletRequest request) throws
664680}
665681```
666682
667- getHandlerInternal方法便是根据url进行查找的过程,可以参见MVC初始化-HandlerMapping初始化一节。下面重点是执行链的生成。
683+ getHandlerInternal方法便是根据url进行查找的过程,可以参见MVC初始化-HandlerMapping初始化一节。下面重点是执行链的生成。
684+
685+ getHandlerExecutionChain方法的原理就是从adaptedInterceptors中获得所有可以适配当前请求URL的MappedInterceptor并将其添加到HandlerExecutionChain的拦截器列表中。拦截器的顺序其实就是我们定义/注册的顺序。
686+
687+ 从getCorsHandlerExecutionChain的源码中可以看出,对于跨域请求其实是向调用链插入了一个CorsInterceptor。
688+
689+ ### 适配器查找
690+
691+ DispatcherServlet.getHandlerAdapter:
692+
693+ ``` java
694+ protected HandlerAdapter getHandlerAdapter(Object handler) {
695+ for (HandlerAdapter ha : this . handlerAdapters) {
696+ if (ha. supports(handler)) {
697+ return ha;
698+ }
699+ }
700+ }
701+ ```
702+
703+ 从前面配置解析-注解驱动可以看出,第一个适配器是RequestMappingHandlerAdapter,而其support方法直接返回true,这就导致了使用的适配器总是这一个。
704+
705+ ## 请求处理
706+
707+ RequestMappingHandlerAdapter.handleInternal:
708+
709+ ``` java
710+ @Override
711+ protected ModelAndView handleInternal(HttpServletRequest request,
712+ HttpServletResponse response, HandlerMethod handlerMethod){
713+ ModelAndView mav;
714+ // Execute invokeHandlerMethod in synchronized block if required.
715+ if (this . synchronizeOnSession) {
716+ HttpSession session = request. getSession(false );
717+ if (session != null ) {
718+ Object mutex = WebUtils . getSessionMutex(session);
719+ synchronized (mutex) {
720+ mav = invokeHandlerMethod(request, response, handlerMethod);
721+ }
722+ } else {
723+ // No HttpSession available -> no mutex necessary
724+ mav = invokeHandlerMethod(request, response, handlerMethod);
725+ }
726+ } else {
727+ // No synchronization on session demanded at all...
728+ mav = invokeHandlerMethod(request, response, handlerMethod);
729+ }
730+ if (! response. containsHeader(HEADER_CACHE_CONTROL )) {
731+ if (getSessionAttributesHandler(handlerMethod). hasSessionAttributes()) {
732+ applyCacheSeconds(response, this . cacheSecondsForSessionAttributeHandlers);
733+ }
734+ else {
735+ prepareResponse(response);
736+ }
737+ }
738+ return mav;
739+ }
740+ ```
741+
742+ ### Session同步
743+
744+ 可以看出,如果开启了synchronizeOnSession,那么** 同一个session的请求将会串行执行** ,这一选项默认是关闭的,当然我们可以通过注入的方式进行改变。
0 commit comments