最后
光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性
Java面试宝典2021版
最常见Java面试题解析(2021最新版)
2021企业Java面试题精选
this.pathLookup.add(path, mapping);
}
String name = null;
“设置HandlerMethod”
if (getNamingStrategy() != null) {
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
}
“”
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
corsConfig.validateAllowCredentials();
this.corsLookup.put(handlerMethod, corsConfig);
}
this.registry.put(mapping,
new MappingRegistration<>(mapping, handlerMethod, directPaths, name, corsConfig != null));
}
finally {
this.readWriteLock.writeLock().unlock();
}
}
mapping参数查看;
mapping 会再之前 detectHandlerMethods 回调方法中 getMappingForMethod进行设置 最后builder (会在这里 通过设计模式 进行Bean的实例化;)
这就是一个Controller 在Spring启动中加载进容器 或者是 装配到 一个名为 pathLookup 中的全过程; 这是前置知识点; 也是必须要了解的; 很多同学私下也问我; 在讲解Spring的时候;希望可以再细致 细腻一些; 作者也努力去把这一块东西讲得透彻; 接下来就进入到了SpringMVC的基本常识.
从深到浅; 以上 我们讲解了Spring 启动的时候 如何把Controller作为配置 加载进入pathLookup 我们根据pathLookup 作为一个垫脚石; 开始详细分析我们SpringMVC 的启动流程; pathLookup有什么作用?
=========================================================================================================================================================================================
#mermaid-svg-1VzyURrVgxolGRck .label{font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family);fill:#333;color:#333}#mermaid-svg-1VzyURrVgxolGRck .label text{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .node rect,#mermaid-svg-1VzyURrVgxolGRck .node circle,#mermaid-svg-1VzyURrVgxolGRck .node ellipse,#mermaid-svg-1VzyURrVgxolGRck .node polygon,#mermaid-svg-1VzyURrVgxolGRck .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-1VzyURrVgxolGRck .node .label{text-align:center;fill:#333}#mermaid-svg-1VzyURrVgxolGRck .node.clickable{cursor:pointer}#mermaid-svg-1VzyURrVgxolGRck .arrowheadPath{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-1VzyURrVgxolGRck .flowchart-link{stroke:#333;fill:none}#mermaid-svg-1VzyURrVgxolGRck .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-1VzyURrVgxolGRck .edgeLabel rect{opacity:0.9}#mermaid-svg-1VzyURrVgxolGRck .edgeLabel span{color:#333}#mermaid-svg-1VzyURrVgxolGRck .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-1VzyURrVgxolGRck .cluster text{fill:#333}#mermaid-svg-1VzyURrVgxolGRck div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-1VzyURrVgxolGRck .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-1VzyURrVgxolGRck text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-1VzyURrVgxolGRck .actor-line{stroke:grey}#mermaid-svg-1VzyURrVgxolGRck .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-1VzyURrVgxolGRck .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-1VzyURrVgxolGRck #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-1VzyURrVgxolGRck .sequenceNumber{fill:#fff}#mermaid-svg-1VzyURrVgxolGRck #sequencenumber{fill:#333}#mermaid-svg-1VzyURrVgxolGRck #crosshead path{fill:#333;stroke:#333}#mermaid-svg-1VzyURrVgxolGRck .messageText{fill:#333;stroke:#333}#mermaid-svg-1VzyURrVgxolGRck .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-1VzyURrVgxolGRck .labelText,#mermaid-svg-1VzyURrVgxolGRck .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-1VzyURrVgxolGRck .loopText,#mermaid-svg-1VzyURrVgxolGRck .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-1VzyURrVgxolGRck .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-1VzyURrVgxolGRck .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-1VzyURrVgxolGRck .noteText,#mermaid-svg-1VzyURrVgxolGRck .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-1VzyURrVgxolGRck .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-1VzyURrVgxolGRck .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-1VzyURrVgxolGRck .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-1VzyURrVgxolGRck .mermaid-main-font{font-family:“trebuchet ms”, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .section{stroke:none;opacity:0.2}#mermaid-svg-1VzyURrVgxolGRck .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-1VzyURrVgxolGRck .section2{fill:#fff400}#mermaid-svg-1VzyURrVgxolGRck .section1,#mermaid-svg-1VzyURrVgxolGRck .section3{fill:#fff;opacity:0.2}#mermaid-svg-1VzyURrVgxolGRck .sectionTitle0{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .sectionTitle1{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .sectionTitle2{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .sectionTitle3{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-1VzyURrVgxolGRck .grid .tick text{font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .grid path{stroke-width:0}#mermaid-svg-1VzyURrVgxolGRck .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-1VzyURrVgxolGRck .task{stroke-width:2}#mermaid-svg-1VzyURrVgxolGRck .taskText{text-anchor:middle;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .taskText:not([font-size]){font-size:11px}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-1VzyURrVgxolGRck .task.clickable{cursor:pointer}#mermaid-svg-1VzyURrVgxolGRck .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-1VzyURrVgxolGRck .taskText0,#mermaid-svg-1VzyURrVgxolGRck .taskText1,#mermaid-svg-1VzyURrVgxolGRck .taskText2,#mermaid-svg-1VzyURrVgxolGRck .taskText3{fill:#fff}#mermaid-svg-1VzyURrVgxolGRck .task0,#mermaid-svg-1VzyURrVgxolGRck .task1,#mermaid-svg-1VzyURrVgxolGRck .task2,#mermaid-svg-1VzyURrVgxolGRck .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutside0,#mermaid-svg-1VzyURrVgxolGRck .taskTextOutside2{fill:#000}#mermaid-svg-1VzyURrVgxolGRck .taskTextOutside1,#mermaid-svg-1VzyURrVgxolGRck .taskTextOutside3{fill:#000}#mermaid-svg-1VzyURrVgxolGRck .active0,#mermaid-svg-1VzyURrVgxolGRck .active1,#mermaid-svg-1VzyURrVgxolGRck .active2,#mermaid-svg-1VzyURrVgxolGRck .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-1VzyURrVgxolGRck .activeText0,#mermaid-svg-1VzyURrVgxolGRck .activeText1,#mermaid-svg-1VzyURrVgxolGRck .activeText2,#mermaid-svg-1VzyURrVgxolGRck .activeText3{fill:#000 !important}#mermaid-svg-1VzyURrVgxolGRck .done0,#mermaid-svg-1VzyURrVgxolGRck .done1,#mermaid-svg-1VzyURrVgxolGRck .done2,#mermaid-svg-1VzyURrVgxolGRck .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-1VzyURrVgxolGRck .doneText0,#mermaid-svg-1VzyURrVgxolGRck .doneText1,#mermaid-svg-1VzyURrVgxolGRck .doneText2,#mermaid-svg-1VzyURrVgxolGRck .doneText3{fill:#000 !important}#mermaid-svg-1VzyURrVgxolGRck .crit0,#mermaid-svg-1VzyURrVgxolGRck .crit1,#mermaid-svg-1VzyURrVgxolGRck .crit2,#mermaid-svg-1VzyURrVgxolGRck .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-1VzyURrVgxolGRck .activeCrit0,#mermaid-svg-1VzyURrVgxolGRck .activeCrit1,#mermaid-svg-1VzyURrVgxolGRck .activeCrit2,#mermaid-svg-1VzyURrVgxolGRck .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-1VzyURrVgxolGRck .doneCrit0,#mermaid-svg-1VzyURrVgxolGRck .doneCrit1,#mermaid-svg-1VzyURrVgxolGRck .doneCrit2,#mermaid-svg-1VzyURrVgxolGRck .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-1VzyURrVgxolGRck .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-1VzyURrVgxolGRck .milestoneText{font-style:italic}#mermaid-svg-1VzyURrVgxolGRck .doneCritText0,#mermaid-svg-1VzyURrVgxolGRck .doneCritText1,#mermaid-svg-1VzyURrVgxolGRck .doneCritText2,#mermaid-svg-1VzyURrVgxolGRck .doneCritText3{fill:#000 !important}#mermaid-svg-1VzyURrVgxolGRck .activeCritText0,#mermaid-svg-1VzyURrVgxolGRck .activeCritText1,#mermaid-svg-1VzyURrVgxolGRck .activeCritText2,#mermaid-svg-1VzyURrVgxolGRck .activeCritText3{fill:#000 !important}#mermaid-svg-1VzyURrVgxolGRck .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck g.classGroup text{fill:#9370db;stroke:none;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family);font-size:10px}#mermaid-svg-1VzyURrVgxolGRck g.classGroup text .title{font-weight:bolder}#mermaid-svg-1VzyURrVgxolGRck g.clickable{cursor:pointer}#mermaid-svg-1VzyURrVgxolGRck g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-1VzyURrVgxolGRck g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-1VzyURrVgxolGRck .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-1VzyURrVgxolGRck .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-1VzyURrVgxolGRck .dashed-line{stroke-dasharray:3}#mermaid-svg-1VzyURrVgxolGRck #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck .commit-id,#mermaid-svg-1VzyURrVgxolGRck .commit-msg,#mermaid-svg-1VzyURrVgxolGRck .branch-label{fill:lightgrey;color:lightgrey;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .slice{font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-1VzyURrVgxolGRck g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-1VzyURrVgxolGRck g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-1VzyURrVgxolGRck g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-1VzyURrVgxolGRck g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-1VzyURrVgxolGRck .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-1VzyURrVgxolGRck .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-1VzyURrVgxolGRck .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-1VzyURrVgxolGRck .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-1VzyURrVgxolGRck .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-1VzyURrVgxolGRck .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-1VzyURrVgxolGRck .edgeLabel text{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:‘trebuchet ms’, verdana, arial;font-family:var(–mermaid-font-family)}#mermaid-svg-1VzyURrVgxolGRck .node circle.state-start{fill:black;stroke:black}#mermaid-svg-1VzyURrVgxolGRck .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-1VzyURrVgxolGRck #statediagram-barbEnd{fill:#9370db}#mermaid-svg-1VzyURrVgxolGRck .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-1VzyURrVgxolGRck .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-1VzyURrVgxolGRck .statediagram-state .divider{stroke:#9370db}#mermaid-svg-1VzyURrVgxolGRck .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-1VzyURrVgxolGRck .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-1VzyURrVgxolGRck .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-1VzyURrVgxolGRck .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-1VzyURrVgxolGRck .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-1VzyURrVgxolGRck .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-1VzyURrVgxolGRck .note-edge{stroke-dasharray:5}#mermaid-svg-1VzyURrVgxolGRck .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{–mermaid-font-family: ‘“trebuchet ms”, verdana, arial’;–mermaid-font-family: “Comic Sans MS”, “Comic Sans”, cursive}#mermaid-svg-1VzyURrVgxolGRck .error-icon{fill:#522}#mermaid-svg-1VzyURrVgxolGRck .error-text{fill:#522;stroke:#522}#mermaid-svg-1VzyURrVgxolGRck .edge-thickness-normal{stroke-width:2px}#mermaid-svg-1VzyURrVgxolGRck .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-1VzyURrVgxolGRck .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-1VzyURrVgxolGRck .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-1VzyURrVgxolGRck .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-1VzyURrVgxolGRck .marker{fill:#333}#mermaid-svg-1VzyURrVgxolGRck .marker.cross{stroke:#333} :root { --mermaid-font-family: “trebuchet ms”, verdana, arial;} #mermaid-svg-1VzyURrVgxolGRck { color: rgba(0, 0, 0, 0.75); font: ; }
Init
service
doGet
doPost
destroy
我们SpringBoot 使用了自动化配置. 但是核心原理不变. 我们的SpringMVC 核心类: DispatcherServlet;; 我们在玩SpringMVC的时候. 我们首先要做的第一件事 就是 在web.xml里面配置DispatcherServlet; 使用其方法拦截我们所有的请求; 分发我们所有的请求;
我们假设说 我们的容器已经启动成功; 现在开始 我们现在将会进行请求
(家里电脑快要报废;没有谷歌 或者火狐; 就随意用了一个游览器.并不影响我们对原理的追溯)
==============================================================================
这个类不陌生吧? 这个类 DispatcherServlet 的父类是->FrameworkServlet 的父类是-> HttpServletBean 的父类是-> HttpServlet 的父类是-> GenericServlet 实现了 Servlet 以上Servlet的生命周期 也就是DispatcherServlet的生命周期; 只不过它的功能更加强大; 我们请求进来被捕获到;
下面我们开始了 SpringMVC 的主流程运转过程:
我们请求的 所有URL 都会被 FrameworkServlet 的service进行拦截; 是所有请求;不管Url后面请求路径是否正确; 凡是这这个端口的请求(包括项目名字)都会被该方法拦截.
该段源码的逻辑很简单。就是获取到请求信息里面的httpMethod; heetMethod 放的 就是Post,Get,Put,Patch,Delete…等等; 在这个方法里面 凡是htteMethod == null的 或者是 PATCH 的就会调用processRequest;其他的 调用HttpServlet 进行分发;
就是得到请求是什么 是Post 还是 Get 或者其他; 我们最后进入super.service 实际上就会进去HttpServlet 的service方法;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
“得到httpServlet 就获取到Get 或者 Post 以下源码非常简单。”
“各位同学请自读就行; 我们以Post为例子;”
String method = req.getMethod();
long lastModified;
if (method.equals(“GET”)) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(“If-Modified-Since”);
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals(“HEAD”)) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals(“POST”)) {
"假设我们 是Post 的请求. 最终会调用HttpServlet 的doPost方法 "
“并且将 request response传入;”
“首先我问一下。 这个this 指的是哪个对象?”
“是HttpServlet 吗? 还是说不是HttpServlet? 下面有图给出答案”
“但是作者希望读者能够自己心里揣着一个答案 往下看”
this.doPost(req, resp);
} else if (method.equals(“PUT”)) {
this.doPut(req, resp);
} else if (method.equals(“DELETE”)) {
this.doDelete(req, resp);
} else if (method.equals(“OPTIONS”)) {
this.doOptions(req, resp);
} else if (method.equals(“TRACE”)) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString(“http.method_not_implemented”);
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
但是DispatcherServlet 没有 doPost方法! 只有他的父类 实现了doPost方法 也就是我们的FrameworkServlet.
来到我们的FrameworkServlet.doPost 方法 :
这里面直接调用了 processRequest
这里注解写得很清楚 只管处理请求 不会去处理结果 结果交给Do service进行处理;
在doService 之前 是封装了 ServletRequestAttributes 实际上就是request response;
这里源码不去细看;因为跟整体流程关系并不是非常大。 学习源码就是 高速公路一路上的风景;或者有警示牌; 或者有加油站;我们要顺着流程继续往下走。 最终到达终点; 其中不明白的地方 我们可以回头再细细的研究;
我们继续往下 到doService 就是我们 DispatcherServlet 的doService 方法中;
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
logRequest(request);
Map<String, Object> 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 上下文参数进行装在。Web_application_context”
“这里留一个悬念; 这个悬念很重要; 如果之前看过源码的同学 应该知道”
“这是什么。之后会有一片详细的文章 介绍”
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 {
“我们纵观我们的do Service方法 他们就是为Request 设置了一堆 Attribute”
“然后委托 doDispatch 调度”
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
开始调度我们的核心方法 DispatcherServlet doDispatch 我们的所有SpringMVC的原理 在市面上的面试 都基本上围绕这个doDispatch 展开的. 如果说问到了doDispatch 前置知识. 在doDispatch前面 做了什么; 细节方面 估计没有多少个人会回答出来; 以下我会把原理 用 ①②③…点全部标记出来 然后配上网上的一张图; 就会很清晰了;
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
"1:我们请求进来 DispatcherServlet "
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
“WebAsyncManager主要用来管理异步请求的处理”
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
“ModelAndView 是返回模型; 目前仅仅是申明 在这里明没有得到具体的 modelAndview”
ModelAndView mv = null;
Exception dispatchException = null;
try {
“封装了当前传入的request请求信息;”
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
“我们在该方法体内 可以跟前面 的pathLookup 对应起来 在getHandler”
“在getHandler方法内部,会根据url 去 pathLookup 里面取MappingInfo”
“2 根据URL 去寻找 HandlerMapping 然后 返回 mappedHandler 回来 DispatcherServlet”
mappedHandler = getHandler(processedRequest);
“如果根据url没找到相对应的 MappingInfo信息 抛出异常;”
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
"3:我们根据 mappedHandler 去找到 HandlerAdapter "
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
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;
}
“4: 通过HandlerAdapter 调用我们具体的requestMapping 请求方法”
“也就是Controller里面的方法 mv 也就是ModelAndView 返回ModelAndView”
“执行完 handle 方法之后 就返回到游览器了;”
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
“找到相对应的是图名称 然后放在ModelAndView的 ViewName 里面”
applyDefaultViewName(processedRequest, mv);
最后
即使是面试跳槽,那也是一个学习的过程。只有全面的复习,才能让我们更好的充实自己,武装自己,为自己的面试之路不再坎坷!今天就给大家分享一个Github上全面的Java面试题大全,就是这份面试大全助我拿下大厂Offer,月薪提至30K!
我也是第一时间分享出来给大家,希望可以帮助大家都能去往自己心仪的大厂!为金三银四做准备!
一共有20个知识点专题,分别是:
Dubbo面试专题
JVM面试专题
Java并发面试专题
Kafka面试专题
MongDB面试专题
MyBatis面试专题
MySQL面试专题
Netty面试专题
RabbitMQ面试专题
Redis面试专题
Spring Cloud面试专题
SpringBoot面试专题
zookeeper面试专题
常见面试算法题汇总专题
计算机网络基础专题
设计模式专题
dis面试专题**
[外链图片转存中…(img-9wWUdLOD-1714965518975)]
Spring Cloud面试专题
[外链图片转存中…(img-LE0xQ80k-1714965518975)]
SpringBoot面试专题
[外链图片转存中…(img-UXpsuPRi-1714965518975)]
zookeeper面试专题
[外链图片转存中…(img-ldOFhqsh-1714965518976)]
常见面试算法题汇总专题
[外链图片转存中…(img-bhNTyIet-1714965518976)]
计算机网络基础专题
[外链图片转存中…(img-cujCzcvU-1714965518976)]
设计模式专题
[外链图片转存中…(img-8YVV5kPR-1714965518976)]