Spring MVC详细源码解析(上篇)
2021-03-10 11:29
标签:rac 另一个 register 情况下 ann lease 暂停 类型 前端 我用的是最原始的Spring MVC使用方式,基于XML文件配置。 导入依赖: spring-webmvc:https://mvnrepository.com/artifact/org.springframework/spring-webmvc javax.servlet-api:https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api web.xml: spring-mvc.xml: webapp文件夹结构: 在Spring MVC中,HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、ViewResolver(视图解析器)成为Spring MVC三大组件。 配置 作用:接收请求、响应结果。相当于转发器、中央处理器。有了DispatcherServlet就减少了其它组件之间的耦合度。 不需要工程师开发,由框架提供。用户请求到达前端控制器,它就相当于MVC模式中的C(Controller),dispatcherServlet是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。 作用:根据请求的URL查找Handler。 不需要工程师开发,由框架提供。HandlerMapping负责根据用户请求找到相应的Handler。 SpringMVC提供了不同的映射器实现不同的映射方式: 配置文件的方式。 实现接口的方式。 注解的方式。 作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler。 不需要工程师开发,由框架提供。 通过HandlerAdapter对Handler进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的Handler进行执行。 作用:处理用户具体的业务请求。 需要工程师开发。Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理。 由于Handler涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发Handler。 编写Handler时需要按照HandlerAdapter的要求去做,这样适配器才可以去正确地执行Handler。 作用:进行视图解析,根据逻辑视图名解析成真正的View。 不需要工程师开发,由框架提供。ViewResolver负责将处理的结果生成View,ViewResolver首先根据逻辑视图名解析成物理视图名(即具体的页面地址),再生成View对象,最后对View进行渲染并将处理结果通过页面展示给用户。 SpringMVC框架提供了很多的View类型:jstlView、freemarkerView、pdfView等。 需要工程师开发。View是一个接口,实现类支持不同的View类型(Jsp、Freemarker、pdf...) Spring MVC是基于组件的方式来执行流程的。 源码按Spring MVC的执行流程逐步分析(依照上面的流程图)。 第一步: 根据执行流程的步骤来,请求最先接触的是DispatcherServlet,它是整个Spring MVC的中央控制器。看名字可知它是一个Servlet,我这里没有指定 既然DispatcherServlet是一个Servlet,我们来回顾一下Servlet的生命周期: 接下来看到DispatcherServlet的初始化init方法,它在间接父类HttpServletBean中,这个方法主要是进行一些最基础内容的初始化,并且提供了initServletBean方法供子类重写,FrameworkServlet类就对该方法进行了重写。 接着寻找DispatcherServlet的service方法,它在父类FrameworkServlet中。先是获取请求的HTTP方法,并将其解析为一个HttpMethod对,HttpMethod是Spring MVC对HTTP方法的再封装。随后判断请求是否为PATCH方法,我们这里是GET方法,故进入父类(HttpServlet类)的service方法。 在HttpServlet类的service方法中,其实也很简单,就是根据不同的HTTP方法进行不同的处理,我们这里进入的是doGet方法。 然后我们进入FramworkServlet类的doGet方法,里面没有什么逻辑,直接调用了另一个processRequest方法。而processRequest方法我们只需要关注它又调用了子类DispatcherServlet的doServlet方法。 DispatcherServlet进到doService方法,这个方法也只需关注它调用了另一个doDispatch方法。 doDispatch是DispatcherServlet中最重要的方法,这个方法的主要作用是分派处理请求的组件。 我们先看到checkMultipart方法,它是用于检查是否需要将当前请求解析为多部分类型请求。先进行一个判断,如果multipartResolver(多部分请求解析器)不存在或者判断当前请求不是多部分类型的请求,就直接退出方法。反之则使用multipartResolver(多部分请求解析器)来解析该请求。 第二步: 然后走到getHandler方法,第二步就是从该方法开始的。DispatcherServlet类中维护了一个名为handlerMappings的List集合,里面保存了两个默认的HandlerMapping(处理器映射器):一个是RequestMappingHandlerMapping,另个一个是BeanNameUrlHandlerMapping。 RequestMappingHandlerMapping:用来处理通过注解来映射请求的Controller,例如@Controller、@RequestMapping等。 BeanNameUrlHandlerMapping:用来处理通过设置控制器Bean的name为请求URL路径的Controller。 getHandler方法会依次遍历每个HandlerMapping接口,直到某个HandlerMapping能获取到HandlerExecutionChain。因为我是使用注解配置的Controller,所以会使用RequestMappingHandlerMapping实现类。 这里会有点绕!先进到RequestMappingHandlerMapping类间接抽象父类AbstractHandlerMapping的getHandler方法。然后会进入第一行代码的getHandlerInternal方法,这个方法在RequestMappingHandlerMapping类中,但是这方法又去到了父类AbstractHandlerMethodMapping的getHandlerInternal方法中。 HandlerMapping结构入下图所示: 先获取到请求的URL路径,然后通过lookupHandlerMethod方法来寻找Handler方法。 暂停一下!这里需要先讲解一下mappingRegistry对象。 先介绍几个跟Handler方法有关的类: isHandler方法主要作用是判断某个类是否是Handler(处理器),判断方法很简单,就是判断该类上是否标有@Controller或@RequestMapping注解。 detectHandlerMethods方法用来检测该指定Handler中的方法有哪些是映射方法,并将映射方法注册到一个名为mappingRegistry的Map集合中,其中Key为RequestMappingInfo,Value为MappingRegistration。 回到上面的lookupHandlerMethod方法,这里主要是通过请求的URL寻找对应的Handler映射方法。 Match:一个包装类,里面存有与请求匹配的RequestMappingInfo和对应的HandlerMethod。 第三步: 随后我们再次回到之前的getHandler方法中,通过getHandlerExecutionChain方法获取了一个包含Handler方法以及多个HandlerInterceptor(处理器拦截器)的HandlerExecutionChain(处理器执行链)。这里面涉及到一个类叫MappedInterceptor,这是映射拦截器,它带有路径模式匹配的HandlerInterceptor,也提供了匹配逻辑来测试拦截器是否适用于一个给定的请求路径。MappedInterceptor类被final关键字修饰,无法被继承,因此大多数的拦截器是否都是存在它内部,比如默认情况下Spring MVC会提供一个ConversionServiceExposingInterceptor(类型转换拦截器)并存入一个MappedInterceptor中,而所有的拦截器又会存储在AbstractHandlerMapping类的adaptedInterceptors集合中。 谈谈这个HandlerExecutionChain,该类里面存储了Handler方法以及装有对应拦截器的List集合,还有前置处理方法、后置处理方法和完成触发方法。 Spring MVC详细源码解析(上篇) 标签:rac 另一个 register 情况下 ann lease 暂停 类型 前端 原文地址:https://www.cnblogs.com/SunnyGao/p/14153227.html前言
项目结构
相关组件
DispatcherServlet(前端控制器)
HandlerMapping(处理器映射器)
HandlerAdapter(处理器适配器)
Handler(处理器)
ViewResolver(视图解析器)
View(视图)
执行流程
源码分析
public final void init() throws ServletException {
// 设置DispatcherServlet的参数,就是
// FrameworkServlet类
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取请求的HTTP方法
HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
processRequest(request, response);
}
else {
super.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 = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince
// FrameworkServlet类
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 省略其他内容...
try {
// 子类DispatcherServlet实现了该方法
doService(request, response);
}
catch (ServletException | IOException ex) {
failureCause = ex;
throw ex;
}
catch (Throwable ex) {
failureCause = ex;
throw new NestedServletException("Request processing failed", ex);
}
finally {
resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}
logResult(request, response, failureCause, asyncManager);
publishRequestHandledEvent(request, response, startTime, failureCause);
}
}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 省略其他内容...
try {
// 分派处理请求的组件
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);
}
}
if (requestPath != null) {
ServletRequestPathUtils.clearParsedRequestPath(request);
}
}
}
// DispatcherServlet类
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
// 处理器执行链
HandlerExecutionChain mappedHandler = null;
// 是否为多部分类型请求
boolean multipartRequestParsed = false;
// 管理异步请求的处理
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
// 模型视图对象
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 检查是否需要将当前请求解析为多部分类型请求
processedRequest = checkMultipart(request);
// 是否解析为
multipartRequestParsed = (processedRequest != request);
// 决定使用哪个Handler来处理当前请求
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 决定使用哪个处理映射器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 获取当前请求的HTTP方法
String method = request.getMethod();
// 如果是GET或HEAD请求,就需要判断资源缓存是否过期
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;
}
// 通过HandlerAdapter执行Handler
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) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 视图解析器解析视图
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()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
// DispatcherServlet类
// 检查是否需要将当前请求解析为多部分类型请求
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
// 先判断是否有多部分类型解析器,只有当存在时才会解析当前请求
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
if (request.getDispatcherType().equals(DispatcherType.REQUEST)) {
logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter");
}
}
// 省略其他内容...
}
return request;
}
// DispatcherServlet类
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
// AbstractHandlerMapping类
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// 省略其他内容...
return executionChain;
}
// RequestMappingHandlerMapping类
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
request.removeAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
try {
return super.getHandlerInternal(request);
}
finally {
ProducesRequestCondition.clearMediaTypesAttribute(request);
}
}
// AbstractHandlerMethodMapping类
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 获取请求URL路径(这里是/hello)
String lookupPath = initLookupPath(request);
this.mappingRegistry.acquireReadLock();
try {
// 根据请求的URL路径寻找Handler中对应的映射方法
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
public abstract class AbstractHandlerMethodMapping
// RequestMappingHandlerMapping类
protected boolean isHandler(Class> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
protected void detectHandlerMethods(Object handler) {
// 获取Handler的Class对象
Class> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
Class> userType = ClassUtils.getUserClass(handlerType);
// 筛选映射方法并存入Map集合中
Map
// AbstractHandlerMethodMapping内部类MappingRegistry类
public void register(T mapping, Object handler, Method method) {
this.readWriteLock.writeLock().lock();
try {
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
validateMethodMapping(handlerMethod, mapping);
// 省略其他内容...
// 将一个映射存入映射注册中心
this.registry.put(mapping, new MappingRegistration(mapping, handlerMethod, directPaths, name));
}
finally {
this.readWriteLock.writeLock().unlock();
}
}
// AbstractHandlerMethodMapping类
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
// 存有与请求匹配的所有Match对象的集合
List
// AbstractHandlerMapping类
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = getHandlerInternal(request);
// 省略其他内容...
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
// 日志打印
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
// 判断是否要处理跨域问题
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = getCorsConfiguration(handler, request);
if (getCorsConfigurationSource() != null) {
CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
config = (globalConfig != null ? globalConfig.combine(config) : config);
}
if (config != null) {
config.validateAllowCredentials();
}
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
// 获取处理器执行链
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
// 初始化处理器执行链
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
// 遍历adaptedInterceptors集合中的拦截器,依次添加进HandlerExecutionChain的interceptorList集合中
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;
}
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
// Handler方法
private final Object handler;
// 拦截器
private final List
文章标题:Spring MVC详细源码解析(上篇)
文章链接:http://soscw.com/index.php/essay/62738.html