首先spring boot 内置了 tomcat服务器:‘
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
当服务启动tomcat开启监听,他监听了端口,请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理;
然后我们看下springmvcdispather的结构图
可以看出dispatcherServlet是继承Frameworkservlet,继承httpservleteBean ,然后继承httpservlet到这就进入tomcat包中了,httpservlet继承GeneticServlet最终实现servlet,所以最终还是实现servlet来处理的
让我们一步一步向下看: tomcat本质也是一个servlet容器
servelt的5个方法就是servlet的生命周期,比较重要的是init 和service,init是做一些初始化的操作,service就是请求进来后需要操作的的
package javax.servlet;
import java.io.IOException;
public interface Servlet {
void init(ServletConfig var1) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
GenericServlet
实现ServletConfig 提供了log方法
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void log(String message) {
this.getServletContext().log(this.getServletName() + ": " + message);
}
public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}
HttpServlet 主要是将ServletRequest转成HttpServletRequest 用于http请求 ,然后对应不同的method调用不同的方法,例如 由doGet doPost等方法具体处理
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException(lStrings.getString("http.non_http"));
}
this.service(request, response);
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
httpservletbean 没有什么改变
frameworkservlet 重写 service方法,调用processRequest 方法,调用doService,doService在dispathcerServlet里面调用 doget,dopost等方法
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
if (httpMethod != HttpMethod.PATCH && httpMethod != null) {
super.service(request, response);
} else {
this.processRequest(request, response);
}
}
dispathcerservlet 重写doService,然后调用this.doDispatch(request, response) 调度
由request找到HandlerMapping
mappedHandler = this.getHandler(processedRequest);
根据HandlerMapping找到HandlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
用HandlerAdapter处理Handler
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
调用processDispatchResult方法处理上面的结果
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}