成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringMVC處理流程非常詳細(xì)的講解

開(kāi)發(fā) 前端
通過(guò)HandlerMapping找到了相應(yīng)的HandlerMethod對(duì)象,最后封裝到了HandlerExecutionChain中,接下來(lái)就是根據(jù)HandlerMethod查找合適的HandlerAdapter處理程序。

1 請(qǐng)求入口

public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 2.1.通過(guò)HandlerMapping獲取請(qǐng)求處理鏈,該對(duì)象由處理程序(Controller,一般HandlerMethod對(duì)象)及攔截器(Interceptor)組成
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 2.2.根據(jù)2.1獲取的處理程序(HandlerMethod)對(duì)象確定能夠處理該處理程序的HandlerAdapter對(duì)象
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// ...
// 2.3.執(zhí)行處理程序之前,執(zhí)行攔截器preHandle方法,如果返回了false,本次請(qǐng)求將被終止
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}

// 2.4.真正的執(zhí)行處理程序
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// ...
// 2.5.執(zhí)行處理程序之后,執(zhí)行攔截器postHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
dispatchException = ex;
} catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 2.6.處理結(jié)果,根據(jù)處理程序是否發(fā)生異常,是否返回有ModelAndView對(duì)象進(jìn)行結(jié)果的處理
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
// ...
}
}

2 處理請(qǐng)求

2.1 獲取請(qǐng)求處理鏈

該步驟通過(guò)HandlerMapping獲取HandlerExecutionChain處理器執(zhí)行鏈。

public class DispatcherServlet {
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
// 遍歷當(dāng)前容器中注冊(cè)的所有HandlerMapping對(duì)象
for (HandlerMapping mapping : this.handlerMappings) {
// 針對(duì)Controller接口,使用的是RequestMappingHandlerMapping對(duì)象
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
}

這里以RequestMappingHandlerMapping為例

mapping.getHandler(request)方法調(diào)用流程如下:

public abstract class AbstractHandlerMapping {
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 調(diào)用子類實(shí)現(xiàn)的getHandlerInternal方法
Object handler = getHandlerInternal(request);
// ...
// 根據(jù)查找到的處理程序封裝到處理程序執(zhí)行鏈
// 這里會(huì)將攔截器也添加其中
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
// ...這里是跨域相關(guān)的配置
return executionChain;
}
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
}

調(diào)用子類RequestMappingInfoHandlerMapping#getHandlerInternal實(shí)現(xiàn)。

public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
try {
// 又調(diào)父類的實(shí)現(xiàn) (⊙o⊙)…
return super.getHandlerInternal(request);
}
}
}

調(diào)用父類AbstractHandlerMethodMapping#getHandlerInternal方法

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
private final MappingRegistry mappingRegistry = new MappingRegistry();
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 根據(jù)當(dāng)前的請(qǐng)求獲取請(qǐng)求的uri
String lookupPath = initLookupPath(request);
this.mappingRegistry.acquireReadLock();
try {
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
}
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<>();
// 系統(tǒng)啟動(dòng)時(shí)初始化RequestMappingHandlerMapping解析了整個(gè)系統(tǒng)中所有的Controller然后注冊(cè)到MappingRegistry中
// 根據(jù)當(dāng)前的請(qǐng)求uri,對(duì)應(yīng)List<RequestMappingInfo>對(duì)象,相同的uri可能對(duì)應(yīng)不同的request method,所以這里返回的是List集合
List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
if (directPathMatches != null) {
// 該方法內(nèi)部會(huì)根據(jù)找到的RequestMappingInfo進(jìn)行遍歷,根據(jù)請(qǐng)求信息逐個(gè)的判斷對(duì)應(yīng)@RequestMapping配置的屬性是否匹配
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
addMatchingMappings(this.mappingRegistry.getRegistrations().keySet(), matches, request);
}
// 下面if的邏輯就是判斷如果找到了匹配并且存在多個(gè)會(huì)找出最合適的
if (!matches.isEmpty()) {
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
bestMatch = matches.get(0);
if (CorsUtils.isPreFlightRequest(request)) {
for (Match match : matches) {
if (match.hasCorsConfig()) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
}
} else {
Match secondBestMatch = matches.get(1);
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.getHandlerMethod().getMethod();
Method m2 = secondBestMatch.getHandlerMethod().getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.getHandlerMethod());
// 將當(dāng)前請(qǐng)求uri保存到request對(duì)象中setAttribute
handleMatch(bestMatch.mapping, lookupPath, request);
// 返回當(dāng)前uri對(duì)應(yīng)的HandlerMethod對(duì)象
return bestMatch.getHandlerMethod();
}
}
protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);
}
}

2.2 獲取HandlerAdapter

在上一步中通過(guò)HandlerMapping找到了相應(yīng)的HandlerMethod對(duì)象,最后封裝到了HandlerExecutionChain中,接下來(lái)就是根據(jù)HandlerMethod查找合適的HandlerAdapter處理程序。

public class DispatcherServlet {
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
// 這里的參數(shù)handler一般都是HandlerMethod對(duì)象
for (HandlerAdapter adapter : this.handlerAdapters) {
// 這個(gè)根據(jù)handler判斷哪個(gè)HandlerAdapter支持,一般都是RequestMappingHandlerAdapter
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
}

RequestMappingHandlerAdapter 這調(diào)用的是父類方法

public abstract class AbstractHandlerMethodAdapter {
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
}
public class RequestMappingHandlerAdapter {
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}
}

2.3 執(zhí)行攔截器preHandle方法

在真正調(diào)用處理程序前,執(zhí)行攔截器preHandle方法

public class HandlerExecutionChain {
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for (int i = 0; i < this.interceptorList.size(); i++) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
// 如果任何一個(gè)攔截器返回了false,本次請(qǐng)求都會(huì)被終止
if (!interceptor.preHandle(request, response, this.handler)) {
// 該攔截器的完成回調(diào)會(huì)被執(zhí)行
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
return true;
}
}

2.4 實(shí)際請(qǐng)求處理

public class DispatcherServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
}

AbstractHandlerMethodAdapter

public abstract class AbstractHandlerMethodAdapter {
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 子類重寫(xiě)了該方法
return handleInternal(request, response, (HandlerMethod) handler);
}
}

RequestMappingHandlerAdapter

public class RequestMappingHandlerAdapter {
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
if (this.synchronizeOnSession) {
// ...
} else {
// No synchronization on session demanded at all...
// 執(zhí)行HandlerMethod調(diào)用
mav = invokeHandlerMethod(request, response, handlerMethod);
}
// ...
return mav;
}
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
// 創(chuàng)建數(shù)據(jù)綁定工廠,主要作用就是將請(qǐng)求的參數(shù)信息與Controller方法的參數(shù)進(jìn)行綁定(數(shù)據(jù)類型的轉(zhuǎn)換)及參數(shù)校驗(yàn)
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
// 處理@ModelAttribute和@SessionAttribute注解,它將做兩件事:
// 1.將@SessionAttribute注解的方法的相關(guān)數(shù)據(jù)合并到下面的ModelAndViewContainer中
// 2.將@ModelAttribute注解的方法返回值添加到ModelAndViewContainer中
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 實(shí)際HandlerMethod調(diào)用對(duì)象
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
// 設(shè)置參數(shù)解析器
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
if (this.returnValueHandlers != null) {
// 設(shè)置Controller方法返回值的處理器
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
// 執(zhí)行上面說(shuō)的兩個(gè)步驟
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
// ...
// 執(zhí)行調(diào)用HandlerMethod
// 在這個(gè)過(guò)程中會(huì)應(yīng)用到參數(shù)解析器和返回值處理器,這里就不展開(kāi)說(shuō)了
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
// 這里會(huì)返回ModelAndView對(duì)象,這個(gè)根據(jù)情況,如果你是RestController,那么在通過(guò)返回值處理器就已經(jīng)將結(jié)果進(jìn)行了輸出如使用@ResponseBody注解的方法
// 如果是RestController,請(qǐng)求結(jié)果就提前輸出了,同時(shí)會(huì)將ModelAndViewContainer的requestHandled屬性設(shè)置為true。
return getModelAndView(mavContainer, modelFactory, webRequest);
} finally {
webRequest.requestCompleted();
}
}
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,
ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {

modelFactory.updateModel(webRequest, mavContainer);
// 如果是@ResponseBody注解的方法,那么直接返回null
if (mavContainer.isRequestHandled()) {
return null;
}
ModelMap model = mavContainer.getModel();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
// ...
return mav;
}
}

2.5 執(zhí)行攔截器postHandle方法

public class HandlerExecutionChain {
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
throws Exception {
for (int i = this.interceptorList.size() - 1; i >= 0; i--) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}
}
}

2.6 處理結(jié)果

public class DispatcherServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {

boolean errorView = false;

// 在處理過(guò)程中如果出現(xiàn)了異常會(huì)進(jìn)入這里進(jìn)行異常處理
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}

// 如果Controller方法返回有ModelAndView
if (mv != null && !mv.wasCleared()) {
// 進(jìn)行視圖的渲染輸出到客戶端
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}

if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}

// 如果是RestController接口,那么上面的代碼都不會(huì)執(zhí)行
if (mappedHandler != null) {
// 執(zhí)行攔截器的afterCompletion回調(diào)方法
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
}

責(zé)任編輯:武曉燕 來(lái)源: 實(shí)戰(zhàn)案例錦集
相關(guān)推薦

2011-06-17 13:39:47

Qt 文件

2011-06-17 13:18:17

Qt 文件

2023-03-08 08:54:59

SpringMVCJava

2010-05-10 15:09:03

Unix文件

2009-04-03 08:21:37

AndroidGoogle移動(dòng)OS

2013-01-10 15:36:44

Android開(kāi)發(fā)組件Intent

2010-01-06 09:40:07

Ubuntu時(shí)間設(shè)置

2010-05-17 16:31:04

IIS Request

2011-06-14 15:39:46

單元測(cè)試

2009-09-25 17:03:29

Hibernate是什

2009-12-14 11:29:19

Linux查看命令

2010-04-29 10:15:01

Unix系統(tǒng)

2010-06-17 12:57:27

如何修復(fù)Grub

2010-05-07 14:11:06

Unix--Tripw

2009-12-03 16:39:09

phpCB批量轉(zhuǎn)換

2010-05-17 09:19:03

Subversion

2009-09-27 17:23:16

Hibernate應(yīng)用

2015-08-25 10:28:38

前端圖片延遲加載

2011-07-06 10:46:33

Xcode

2021-01-04 05:42:48

數(shù)倉(cāng)模型設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 99久久久99久久国产片鸭王 | 久久精品国产久精国产 | 久久久久久久久久久爱 | 国产精品亚洲综合 | 天天摸天天干 | 亚洲欧美综合 | 99爱在线观看 | 国产精品区二区三区日本 | 亚洲日本免费 | 18av在线播放 | 欧美日韩亚洲视频 | 精品国产欧美 | 欧美一区二区在线看 | 日日草天天干 | 精品在线免费看 | 成人国内精品久久久久一区 | 亚洲精品成人在线 | 91精品国产一区 | 91在线电影 | 亚洲入口 | 国产在线一区二区 | 精品日韩| 2020亚洲天堂| 国产精品久久久久久一级毛片 | 中文字幕国产日韩 | 密色视频 | a级免费黄色片 | 91视频电影 | 亚洲天堂av网| 国产91精品在线 | 国产综合视频 | 国产欧美精品一区二区色综合朱莉 | 欧美日韩成人一区二区 | 亚洲精品无人区 | 91观看 | 91免费看片 | 青青草国产在线观看 | 国产在线观看一区二区三区 | 国产91一区 | 成人亚洲网 | 日韩中文字幕在线视频 |