一、springmvc啟動加載流程
1、引入spring-web.jar包時,在這個包的META-INF/services/javax.servlet.ServletContainerInitializer文件中定義的加載類SpringServletContainerInitializer,提供給springmvc實現初始化的操作。
2、在SpringServletContainerInitializer類中,通過@HandlesTypes來引入WebApplicationInitializer。
3、自己自定義的啟動類只要繼承了WebApplicationInitializer類并實現了onStartUp方法,那么servlet容器在啟動的時候就會拿到自己自定義的啟動類,并開始啟動。
啟動原理:servlet容器在初始化的時候會加載到SpringServletContainerInitializer類,然后這個類中通過@HandlesTypes來引入WebApplicationInitializer子類,然后回調傳遞ServletContext上下文,此處使用的是模板方法。
springmvc是如何來替代web.xml的?核心就是使用的SpringServletContainerInitializer類。
二、攔截器與過濾器區別
相同點:
????????攔截器和過濾器都是基于Aop實現,能夠對請求執行之前和之后實現攔截。
不同點:
????????過濾器是基于Servlet容器實現,對Web請求之前和之后實現攔截
????????攔截器不需要依賴于Servlet、不僅可以實現Web請求進行攔截,還有對其他方法攔截等。
????????過濾器比攔截器先執行,攔截器封裝的方法比過濾器攔截使用起來更加簡單。
應用場景:
????????攔截器:權限控制、日志打印、參數驗證、會話信息。
????????過濾器:編碼轉換、跨域解決、xss攻擊。
三、DispatcherServlet底層源碼分析
1.執行doDispatch;
2.調用getHandler方法獲取請求目標的方法 ?也就是? 請求url映射路徑對應的控制層具體的方法;
handlerMappings的作用查找控制器位置,比如xml和注解方式;
3.調用getHandlerAdapter獲取控制層適配器 RequestMappingHandlerAdapter;
4.執行攔截器前置方法 preHandle() 如果返回為true的話;
5.執行實際請求目標方法 返回modeAndView對象;
6.執行攔截器PostHandle()方法;
7.設置渲染視圖層內容;
8.執行攔截器afterCompletion方法;
四、SpringMVC控制對象初始化流程
1、HttpServletBean類的init() 方法2、FrameworkServlet類的initServletBean() 方法 → ?initWebApplicationContext()3、DispatcherServlet類的onRefresh() 方法 → ?initStrategies()方法
protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);//初始化上傳文件解析器(或者是多部分請求解析器)initLocaleResolver(context);//初始化本地化解析器initThemeResolver(context);//初始化主題解析器initHandlerMappings(context);//初始化處理器映射器initHandlerAdapters(context);//初始化處理器適配器initHandlerExceptionResolvers(context);//初始化處理器異常解析器initRequestToViewNameTranslator(context);//初始化請求到視圖名翻譯器initViewResolvers(context);//初始化視圖解析器initFlashMapManager(context);//初始化重定向數據管理器
}
五、SpringMVC中的適配器
????????適配器模式:將一個系統的接口轉換成另外一種形式,從而使原來不能直接調用的接口變得可以調用。使用適配器可以針對不容的handler類型找到不同的適配器來實現執行目標方法。
SpringMVC中有以下幾種適配器:
1、繼承Controller方式所使用的適配器:SimpleControllerHandlerAdapter
2、 HTTP請求處理器適配器:HttpRequestHandlerAdapter
3、注解方式(@Controller)的處理器適配器:RequestMappingHandlerAdapter
適配器模式應用場景
1.?? Mybatis多種日志框架的整合(logback、log4j)
2.?? SpringMVC適配器模式
3.?? 新老版本的兼容問題
適配器模式源碼分析
1.使用getHandlerAdapter獲取對應的hanlder的具體HandlerAdapter2.HandlerAdapter接口有如下的子 c處理請求適配器2.1繼承Controller方式所使用的適配器:SimpleControllerHandlerAdapter2.2 HTTP請求處理器適配器:HttpRequestHandlerAdapter 2.3注解方式(@Controller)的處理器適配器:RequestMappingHandlerAdapter如果不采用適配器的話 :
If(hanlder instanceof Controller){// 執行Controller適配器
}If(hanlder instanceof? HttpControler){// 執行我們的HttpController
}If(hanlder instanceof? ServletControler){// 執行我們的HttpController
}If(hanlder instanceof? AnnotationControler){// 執行我們的AnnotationController
}
六、SpringMvc異步實現方式
異步支持需要注意的兩個地方
* 1、config類中開啟異步@EnableAsync
* 2、初始化類中 dynamic.setAsyncSupported(true);//開啟springmvc異步
1、第一種方式:直接在接口上添加@Async注解來實現
@Async
public String getMember(){try {System.out.println("2、業務處理開始,線程名稱"+Thread.currentThread().getContextClassLoader());Thread.sleep(3000);System.out.println("3、業務處理完畢,線程名稱"+Thread.currentThread().getContextClassLoader());}catch (Exception e){e.printStackTrace();}return "member";
}
2、第二種方式:使用Callable類的方式
/*** 異步支持需要注意的兩個地方* 1、config類中開啟異步@EnableAsync* 2、初始化類中 dynamic.setAsyncSupported(true);//開啟springmvc異步* Callable這種方式也是需要等業務線程處理完畢后,才會返回給客戶端,為了避免等待時間,可以在客戶端寫一個定時器來查詢處理結果*/
@RequestMapping("/asyncMember")
@ResponseBody
public Callable<String> asyncMember(){Callable<String> callable = new Callable<String>() {public String call() throws Exception {//耗時的時間都可以放在這個里面去處理String member = memberService.getMember();return member;}};return callable;
}