無(wú)XML整合
1.根據(jù)Serlvet3-1規(guī)范,可以動(dòng)態(tài)的注冊(cè)@WebServlet、@WebFilter、@WebListener
以WebServlet為例,這樣就可以不用寫servlet的xml配置了。spring利用這個(gè)特性完成無(wú)配置的springmvc整合。
public class MySpringServletContainerInitializer extends ServletContainerInitializer{
@Override
public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
// 通過(guò)servletContext動(dòng)態(tài)添加Servlet
servletContext.addServlet("spiServlet", new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("spiServlet--doGet");
}
}).addMapping("/spiServlet.do");
}
- a.外置Tomcat啟動(dòng)的時(shí)候通過(guò)SPI 找到我們應(yīng)用中的/METAINF/service/javax.servlet.ServletContainerInitializer
- b.調(diào)用SpringServletContainerInitializer.onStartUp(),@HandlesTypes(WebApplicationInitializer.class) 會(huì)找到所有實(shí)現(xiàn)WebApplicationInitializer接口的類,傳入onStartUp方法,所有的實(shí)現(xiàn)類會(huì)生成spring的父子容器,DispatcherServlet,讓所有的請(qǐng)求都由DispatcherServlet處理。ContextLoaderListener放入ServletContext,到時(shí)tomcat就會(huì)調(diào)用contextInitialized方法。
3.初始化ContextLoaderListener,contextInitialized調(diào)用父容器的refresh方法并把父容器servlet放入上下文。
4.初始化DispatcherServlet,tomcat會(huì)幫我們調(diào)用DispatcherServlet#init(),這個(gè)方法會(huì)獲取到之前的父容器,并將現(xiàn)在的子容器設(shè)置父容器,注入子容器的監(jiān)聽器并調(diào)用refresh方法,執(zhí)行完后,子容器的監(jiān)聽器就會(huì)收到事件
5.事件處理會(huì)初始化解析器、web上下文、主題解析器、HandlerMapping、HandlerAdapters、異常解析器對(duì)象、ViewResolvers處理器。為springmcv后續(xù)請(qǐng)求做準(zhǔn)備。
請(qǐng)求流程處理
1.前端處理器 DispatcherServlet
接受所有請(qǐng)求,分發(fā)到各個(gè)控制器
2.處理器映射器 HandlerMapping
匹配請(qǐng)求的url,匹配上了返回Handler處理器(處理器和處理器攔截器攔截器),即controller里面的方法和定義的攔截器
3.處理器適配器 HandlerAdapter
負(fù)責(zé)調(diào)用Handler-具體的方法- 返回視圖的名字 Handler將它封裝到ModelAndView(封裝視圖名,request域的數(shù)據(jù))
4.處理器(后端控制器) Handler
controller里面的方法,如果返回responsebody,則直接返回json數(shù)據(jù),不走視圖邏輯
5.視圖解析器 ViewReslover
根據(jù)ModelAndView里面的視圖名地址去找到具體的jsp封裝在View對(duì)象中
6.view視圖
進(jìn)行視圖渲染(將jsp轉(zhuǎn)換成html內(nèi)容 --這是Servlet容器的事情了) 最終response到的客戶端