SpringMVC源码解析一-成都快上网建站

SpringMVC源码解析一

服务器接收到从浏览器发送的一个请求后, 首先进入HttpServlet#service()方法中

站在用户的角度思考问题,与客户深入沟通,找到铜山网站设计与铜山网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站建设、网站制作、企业官网、英文网站、手机端网站、网站推广、空间域名、网页空间、企业邮箱。业务覆盖铜山地区。

HttpServlet#service()方法实现:

@Override

public void service(ServletRequest req, ServletResponse res)

throws ServletException, IOException {

HttpServletRequest request;

HttpServletResponse response;

try {

request = (HttpServletRequest) req;

response = (HttpServletResponse) res;

} catch (ClassCastException e) {

throw new ServletException(lStrings.getString("http.non_http"));

}

service(request, response);

}

protected void service(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException {

String method = req.getMethod();

if (method.equals(METHOD_GET)) {

long lastModified = getLastModified(req);

if (lastModified == -1) {

// servlet doesn't support if-modified-since, no reason

// to go through further expensive logic

doGet(req, resp);

} else {

long ifModifiedSince;

try {

ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

} catch (IllegalArgumentException iae) {

// Invalid date header - proceed as if none was set

ifModifiedSince = -1;

}

if (ifModifiedSince < (lastModified / 1000 * 1000)) {

// If the servlet mod time is later, call doGet()

// Round down to the nearest second for a proper compare

// A ifModifiedSince of -1 will always be less

maybeSetLastModified(resp, lastModified);

doGet(req, resp);

} else {

resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

}

}

} else if (method.equals(METHOD_HEAD)) {

long lastModified = getLastModified(req);

maybeSetLastModified(resp, lastModified);

doHead(req, resp);

} else if (method.equals(METHOD_POST)) {

doPost(req, resp);

} else if (method.equals(METHOD_PUT)) {

doPut(req, resp);

} else if (method.equals(METHOD_DELETE)) {

doDelete(req, resp);

} else if (method.equals(METHOD_OPTIONS)) {

doOptions(req,resp);

} else if (method.equals(METHOD_TRACE)) {

doTrace(req,resp);

} else {

String errMsg = lStrings.getString("http.method_not_implemented");

Object[] errArgs = new Object[1];

errArgs[0] = method;

errMsg = MessageFormat.format(errMsg, errArgs);

resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

}

}

在HttpServlet#service(request, response)中调用根据请求类型调用不同的实现方法, doGet, doPost等; 这里发送的是get请求, 因此看doGet()的实现;

FrameworkServlet#doGet()方法的实现:

@Override

protected final void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

proce***equest(request, response);

}

FrameworkServlet#proce***equest()方法实现:

protected final void proce***equest(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

long startTime = System.currentTimeMillis();

Throwable failureCause = null;

LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();

LocaleContext localeContext = buildLocaleContext(request);

RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();

ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());

initContextHolders(request, localeContext, requestAttributes);

try {

/**

* 请求逻辑处理

* {@link DispatcherServlet#doService(HttpServletRequest,HttpServletResponse)}

*/

doService(request, response);

}

. . . . . .

}

DispatcherServlet#doService()方法实现

@Override

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {

if (logger.isDebugEnabled()) {

String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";

logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +

" processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");

}

// 设置快照

Map attributesSnapshot = null;

if (WebUtils.isIncludeRequest(request)) {

attributesSnapshot = new HashMap<>();

Enumeration attrNames = request.getAttributeNames();

while (attrNames.hasMoreElements()) {

String attrName = (String) attrNames.nextElement();

if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {

attributesSnapshot.put(attrName, request.getAttribute(attrName));

}

}

}

// 使框架对象可用于处理程序并查看对象

request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());

request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);

request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);

request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

if (this.flashMapManager != null) {

FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);

if (inputFlashMap != null) {

request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));

}

request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());

request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

}

try {

/**

* 核心逻辑处理

*/

doDispatch(request, response);

}

finally {

if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {

//使用快照恢复Request属性

if (attributesSnapshot != null) {

restoreAttributesAfterInclude(request, attributesSnapshot);

}

}

}

}

DispatcherServlet#doDispatch()方法实现

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

HttpServletRequest processedRequest = request;

HandlerExecutionChain mappedHandler = null;

boolean multipartRequestParsed = false;

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {郑州人流医院 http://www.zykdfk.com/

ModelAndView mv = null; //封装view和数据信息

Exception dispatchException = null; //封装异常信息

try {

processedRequest = checkMultipart(request);

multipartRequestParsed = (processedRequest != request);

/**

* 1. 获取处理器

* mappedHandler: HandlerExecutionChain

*/

mappedHandler = getHandler(processedRequest);

if (mappedHandler == null) {

noHandlerFound(processedRequest, response);

return;

}

/**

* 2. 获取适配器

*/

HandlerAdapter ha = 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 (logger.isDebugEnabled()) {

logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);

}

if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {

return;

}

}

/**

* 执行HandlerExecutionChain中的拦截器

*/

if (!mappedHandler.applyPreHandle(processedRequest, response)) {

return;

}

/**

* 3. 通过适配器执行处理器, 也就是我们编写的Controller类; 注意: 这里调用的是适配器的handle()方法

* {@link AbstractHandlerMethodAdapter#handle(HttpServletRequest, HttpServletResponse, Object)}

*

* mv: ModelAndView实例{@link AbstractHandlerMethodAdapter#handle(HttpServletRequest,HttpServletResponse, Object)}

*/

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

if (asyncManager.isConcurrentHandlingStarted()) {

return;

}

applyDefaultViewName(processedRequest, mv);

mappedHandler.applyPostHandle(processedRequest, response, mv);

}

catch (Exception ex) {

dispatchException = ex;

}

catch (Throwable err) {

// As of 4.3, we're processing Errors thrown from handler methods as well,

// making them available for @ExceptionHandler methods and other scenarios.

dispatchException = new NestedServletException("Handler dispatch failed", err);

}

/**

* 4. 视图解析

*/

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

}

catch (Exception ex) {

triggerAfterCompletion(processedRequest, response, mappedHandler, ex);

}

catch (Throwable err) {

triggerAfterCompletion(processedRequest, response, mappedHandler,

new NestedServletException("Handler processing failed", err));

}

finally {

if (asyncManager.isConcurrentHandlingStarted()) {

// Instead of postHandle and afterCompletion

if (mappedHandler != null) {

mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);

}

}

else {

// Clean up any resources used by a multipart request.

if (multipartRequestParsed) {

cleanupMultipart(processedRequest);

}

}

}

}

分析(注: 以下模块解析比较复杂, 拆分为不同播客分析):

根据请求信息获取对应处理器

根据映射处理器获取对应的适配器

通过适配器执行处理器, 也就是编写的Controller类中的相应方法

视图解析

请求解析过程图


网站栏目:SpringMVC源码解析一
文章路径:http://kswjz.com/article/ppgpoj.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流