当前位置: 首页 > news >正文

对视频播放网站做性能测试/抖音seo供应商

对视频播放网站做性能测试,抖音seo供应商,个人免费简历模板,人力资源网站建设计划书springmvc 的请求处理过程(精编) 1. DispacherServlet 前端控制器接受发送过来的请求,交给HandlerMapping 处理映射器, 2. HandlerMapping 处理映射器, 根据请求找到相应的HandlerAdapter 处理适配器(处理适配器就是那些拦截器活着吧Controll…

springmvc 的请求处理过程(精编)

 

1. DispacherServlet 前端控制器接受发送过来的请求,交给HandlerMapping 处理映射器,

2. HandlerMapping 处理映射器, 根据请求找到相应的HandlerAdapter 处理适配器(处理适配器就是那些拦截器活着吧Controller)

3. HandlerAdapter处理器适配器,处理一些功能请求, 返回一个ModleAndView 对象,包括模型数据、逻辑视图名。

ViewResolver视图解析器 ,先根据ModleAndView 中设置的view 解析具体视图

5. 然后将Modle模型中得数据渲染到View中。

这些过程都是以DispatchServlet 为中轴线进行的。

 

首先说说:HandlerMapping 视图解析器的接口

作用是根据当前请求的找到对应的Handler 并将Handler(执行程序) 与一对HandlerInterceptor(拦截器)封装到HandlerExecutionChain 对象中。在HandlerMapping接口的内部只有一个方法,如下

  • HandlerExecutionChain getHandler(HttpServletRequest request);

HandlerMapping 是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler,而 HandlerMapping 具体有哪些实现类下面就会详细分析。

 

 HandlerMapping 实现类有两个分支,分别继承自 AbstractHandlerMethodMapping(得到 HandlerMethod)和 AbstractUrlHandlerMapping(得到 HttpRequestHandler、Controller 或 Servlet),它们又统一继承于AbstractHandlerMapping

 

 

先来看一下 AbstractHandlerMapping,它实现了 HandlerMapping 接口中的 getHandler() 方法,源码如下所示:

@Override

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

// 根据请求获取执行程序,具体的获取方式由子类决定,getHandlerInternal() 是抽象方法

Object handler = getHandlerInternal(request);

if (handler == null) {

handler = getDefaultHandler();

}

if (handler == null) {

return null;

}

// Bean name or resolved handler?

if (handler instanceof String) {

String handlerName = (String) handler;

handler = getApplicationContext().getBean(handlerName);

}

// 将 Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

return getHandlerExecutionChain(handler, request);

}

//  Handler 与一堆拦截器包装到 HandlerExecutionChain 对象中

 

可以看到在这个方法中又调用了 getHandlerInternal() 方法获取到了 Handler 对象,而 Handler 对象具体内容是由它的子类去定义的。下面就来一看下 AbstractHandlerMapping 的两个分支子类。

 

2):AbstractHandlerMethodMapping

AbstractHandlerMethodMapping 这个分支获取的 Handler 的类型是 HandlerMethod,即这个 Handler 是一个方法,它保存了方法的信息(如Method),这样一个 Controller 就可以处理多个请求了,源码如下所示:

 

@Override

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {

// 根据当前请求获取“查找路径” 从 HttpServletRequest中获取请求的路径。

String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);

// 获取当前请求最佳匹配的处理方法(即Controller类的方法中)(获取请求中的方法)

HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);

}

 

 

 

下面的是 lookupHandlerMethod(lookupPath, request); 的方法体:

@Nullable

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {

List<AbstractHandlerMethodMapping<T>.Match> matches = new ArrayList();

//根据请的路径找到 直接访问的路径。

List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);

if (directPathMatches != null) {

this.addMatchingMappings(directPathMatches, matches, request);

}

 

if (matches.isEmpty()) {

this.addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);

}

 

if (!matches.isEmpty()) {

Comparator<AbstractHandlerMethodMapping<T>.Match> comparator = new AbstractHandlerMethodMapping.MatchComparator(this.getMappingComparator(request));

Collections.sort(matches, comparator);

if (this.logger.isTraceEnabled()) {

this.logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches);

}

 

AbstractHandlerMethodMapping<T>.Match bestMatch = (AbstractHandlerMethodMapping.Match)matches.get(0);

if (matches.size() > 1) {

if (CorsUtils.isPreFlightRequest(request)) {

return PREFLIGHT_AMBIGUOUS_MATCH;

}

 

AbstractHandlerMethodMapping<T>.Match secondBestMatch = (AbstractHandlerMethodMapping.Match)matches.get(1);

if (comparator.compare(bestMatch, secondBestMatch) == 0) {

Method m1 = bestMatch.handlerMethod.getMethod();

Method m2 = secondBestMatch.handlerMethod.getMethod();

throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" + request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");

}

}

 

this.handleMatch(bestMatch.mapping, lookupPath, request);

return bestMatch.handlerMethod;

else {

return this.handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);

}

}

上述代码中 lookupHandlerMethod() 方法主要工作是在 Map<T, HandlerMethod> handlerMethods 中找到 HandlerMethod,这里的 T 是 HandlerMappingInfo,它封装了 @RequestMapping 注解中的信息。那 HandlerMethod 是怎么创建的(即怎么把 Controller 的方法变成了它),

即: mapping 与handlerMethod(处理方法的)关系;

继续看一下源码找到 initHandlerMethods() 方法,这个方法是在这个类创建后调用的,如下所示是它的源码:

 

protected void initHandlerMethods() {

// 从容器中获取所有 Bean 的名称,detectHandlerMethodsInAncestorContexts 默认false,不从父容器中查找

//即默认只查找 SpringMVC 的 IOC 容器,不查找它的父容器 Spring 的 IOC 容器

String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?

BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :

getApplicationContext().getBeanNamesForType(Object.class));

for (String beanName : beanNames) {

// 这里的 isHandler()方法由子类实现,判断是否拥有 @Controller 注解或 @RequestMapping 注解

if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(beanName))){

// 利用反射得到 Bean 中的 Method 并包装成 HandlerMethod,然后放入 Map 中

detectHandlerMethods(beanName);

}

}

handlerMethodsInitialized(getHandlerMethods());

}

看完上述代码后,可以知道是在 detectHandlerMethods() 方法中将 Bean 的方法转换为 HandlerMethod 对象,具体实现如下

 

protected void detectHandlerMethods(final Object handler) {

// 获取这个 Bean 的 Class 对象

Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());

// 避免重复调用 getMappingForMethod(),getMappingForMethod() 将重新构建 RequestMappingInfo 实例

final Map<Method, T> mappings = new IdentityHashMap<Method, T>();

// 获取被代理前的原始类型

final Class<?> userType = ClassUtils.getUserClass(handlerType);

// 获取 Method

Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {

@Override

public boolean matches(Method method) {

// 根据 Method 和它的 @RequestMapping 注解,创建 RequestMappingInfo 对象。

// 这里的 T 就是 RequestMappingInfo,它封装了 @RequestMapping 信息

T mapping = getMappingForMethod(method, userType);

if (mapping != null) {

mappings.put(method, mapping);

return true;

} else {

return false;

}

}

});

for (Method method : methods) {

// 注册 Method 和它的映射,RequestMappingInfo 储存着映射信息

registerHandlerMethod(handler, method, mappings.get(method));

}

}

 

最后在 registerHandlerMethod() 方法中,将 RequestMappingInfo 作为 key,把 Method 包装成HandlerMethod 作为 value 添加到了 Map<T, HandlerMethod> handlerMethods 中。

 

protected void registerHandlerMethod(Object handler, Method method, T mapping) {

HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);

HandlerMethod oldHandlerMethod = this.handlerMethods.get(mapping);

if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {

throw new IllegalStateException("");

}

this.handlerMethods.put(mapping, newHandlerMethod);

Set<String> patterns = getMappingPathPatterns(mapping);

for (String pattern : patterns) {

if (!getPathMatcher().isPattern(pattern)) {

this.urlMap.add(pattern, mapping);

}

}

}

 

 

接下来我们接着看看:HandlerAdapter

根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象。HandlerAdapter 接口中的方法如下:

 

HandlerAdapter的接口的方法:

public interface HandlerAdapter {

boolean supports(Object var1);

ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

 

long getLastModified(HttpServletRequest var1, Object var2);

}

 

该接口的具体的实现类有:

HttpRequestHandlerAdapterSimpleControllerHandlerAdapterAnnotationMethodHandlerAdapter,这个三个类是具体实现HandlerAdapter这个接口的三个类;

1 RequestMappingHandlerAdapter

从上面的文章中可以知道,利用 RequestMappingHandlerMapping 获取的 Handler 是 HadnlerMethod 类型,它代表 Controller 里要执行的方法,而 RequestMappingHandlerAdapter 可以执行 HadnlerMethod 对象。

RequestMappingHandlerAdapter 的 handle()方法是在它的父类 AbstractHandlerMethodAdapter 类中实现的,源码如下所示

 

@Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }

 

handleInternal() 方法是由 RequestMappingHandlerAdapter 自己来实现的,源码如下所示

 

@Override

protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

// 是否通过 @SessionAttributes 注释声明了 session 属性。

if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {

checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);

} else {

checkAndPrepare(request, response, true);

}

// 是否需要在 synchronize 块中执行

if (this.synchronizeOnSession) {

HttpSession session = request.getSession(false);

if (session != null) {

Object mutex = WebUtils.getSessionMutex(session);

synchronized (mutex) {

// 执行 HandlerMethod

return invokeHandleMethod(request, response, handlerMethod);

}

}

}

// 执行 HandlerMethod,得到 ModelAndView

return invokeHandleMethod(request, response, handlerMethod);

}

 

继续再来看一下如何得到 ModelAndViewinvokeHandlerMethod() 方法如下

 

private ModelAndView invokeHandleMethod(HttpServletRequest request,

HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

//

ServletWebRequest webRequest = new ServletWebRequest(request, response);

// 数据绑定

WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);

ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// 绑定参数,执行方法

ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);

// 创建模型和视图容器

ModelAndViewContainer mavContainer = new ModelAndViewContainer();

// 设置FlasgMap中的值

mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));

// 初始化模型

modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);

mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

 

AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);

asyncWebRequest.setTimeout(this.asyncRequestTimeout);

 

final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

asyncManager.setTaskExecutor(this.taskExecutor);

asyncManager.setAsyncWebRequest(asyncWebRequest);

asyncManager.registerCallableInterceptors(this.callableInterceptors);

asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

if (asyncManager.hasConcurrentResult()) {

Object result = asyncManager.getConcurrentResult();

mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];

asyncManager.clearConcurrentResult();

requestMappingMethod = requestMappingMethod.wrapConcurrentResult(result);

}

requestMappingMethod.invokeAndHandle(webRequest, mavContainer);

if (asyncManager.isConcurrentHandlingStarted()) {

return null;

}

return getModelAndView(mavContainer, modelFactory, webRequest);

}

 

 

2 HttpRequestHandlerAdapter

HttpRequestHandlerAdapter 可以执行 HttpRequestHandler 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((HttpRequestHandler) handler).handleRequest(request, response); return null; }

 

3 SimpleControllerHandlerAdapter

SimpleControllerHandlerAdapter 可以执行 Controller 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); }

 

4 SimpleServletHandlerAdapter 

SimpleServletHandlerAdapter 可以执行 Servlet 类型的 Handler,源码如下

@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ((Servlet) handler).service(request, response); return null; }

 

ModelAndView resolveException(HttpServletRequest req, HttpServletResponse res, Object handler, Exception ex); 

 

转载于:https://www.cnblogs.com/wangdong811/p/10300247.html

http://www.jmfq.cn/news/4787983.html

相关文章:

  • 电信网站备案流程图/蚁百杭州网站seo优化
  • 乐清 做网站 多少钱/百度有哪些app产品
  • 微信服务号菜单链接网站怎么做的/疫情放开最新消息今天
  • 学校html网站模板代码/淘宝关键词优化技巧
  • 做污事网站/想做电商怎么入手
  • 网站推广成功案例/中国百强企业榜单
  • 广州番禺服装网站建设/谷歌seo关键词优化
  • 湖南常德天气/seo排名优化厂家
  • 可以做fiting网站/网络营销策划书应该怎么写
  • 做视频的素材网站/网络营销案例
  • 大连金州网站建设/网站优化检测
  • 做网站写个人日志/可以发广告的平台
  • 做网站排名费用多少/有效的网络推广
  • 域名和网站/最新的全国疫情数据
  • 小手工制作简单又漂亮/seo怎么读
  • 微网站制作工具有哪些/深圳推广公司哪家最好
  • 沙河网站建设/搜狗搜索旧版本
  • 做网站价格和配置/seo都用在哪些网站
  • 做网站后台都要自己写吗/销售怎么做
  • 国外做仿牌网站/网站权重一般有几个等级
  • 深圳网站建设高端/百度网盘网页版官网
  • 自己电脑做网站服务器系统/2021近期时事新闻热点事件简短
  • 万州哪里有做网站的/专业制作网站的公司哪家好
  • 要看网现在的地址是多少/东莞seo排名外包
  • 随州什么公司做网站/seo1域名查询
  • 完整的网站开发/百度seo怎么操作
  • 佛山教育平台网站建设/广告网站策划方案
  • 福建大舟建设集团有限公司 网站/江门网站建设模板
  • 空调维修技术支持东莞网站建设/打开一个网站
  • 专门做影评的网站/东莞今日新闻大事