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

SpringMvc的原理深度剖析及源码解读

一、springmvc启动加载流程

1、引入spring-web.jar包时,在这个包的META-INF/services/javax.servlet.ServletContainerInitializer文件中定义的加载类SpringServletContainerInitializer,提供给springmvc实现初始化的操作。

2、在SpringServletContainerInitializer类中,通过@HandlesTypes来引入WebApplicationInitializer。

3、自己自定义的启动类只要继承了WebApplicationInitializer类并实现了onStartUp方法,那么servlet容器在启动的时候就会拿到自己自定义的启动类,并开始启动。

启动原理:servlet容器在初始化的时候会加载到SpringServletContainerInitializer类,然后这个类中通过@HandlesTypes来引入WebApplicationInitializer子类,然后回调传递ServletContext上下文,此处使用的是模板方法。

springmvc是如何来替代web.xml的?核心就是使用的SpringServletContainerInitializer类。

二、拦截器与过滤器区别

相同点:

        拦截器和过滤器都是基于Aop实现,能够对请求执行之前和之后实现拦截。

不同点:

        过滤器是基于Servlet容器实现,对Web请求之前和之后实现拦截

        拦截器不需要依赖于Servlet、不仅可以实现Web请求进行拦截,还有对其他方法拦截等。

        过滤器比拦截器先执行,拦截器封装的方法比过滤器拦截使用起来更加简单。

应用场景:

        拦截器:权限控制、日志打印、参数验证、会话信息。

        过滤器:编码转换、跨域解决、xss攻击。

三、DispatcherServlet底层源码分析

1.执行doDispatch;

2.调用getHandler方法获取请求目标的方法  也就是  请求url映射路径对应的控制层具体的方法;

handlerMappings的作用查找控制器位置,比如xml和注解方式;

3.调用getHandlerAdapter获取控制层适配器 RequestMappingHandlerAdapter;

4.执行拦截器前置方法 preHandle() 如果返回为true的话;

5.执行实际请求目标方法 返回modeAndView对象;

6.执行拦截器PostHandle()方法;

7.设置渲染视图层内容;

8.执行拦截器afterCompletion方法;

四、SpringMVC控制对象初始化流程

1、HttpServletBean类的init() 方法2、FrameworkServlet类的initServletBean() 方法 →  initWebApplicationContext()3、DispatcherServlet类的onRefresh() 方法 →  initStrategies()方法
protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);//初始化上传文件解析器(或者是多部分请求解析器)initLocaleResolver(context);//初始化本地化解析器initThemeResolver(context);//初始化主题解析器initHandlerMappings(context);//初始化处理器映射器initHandlerAdapters(context);//初始化处理器适配器initHandlerExceptionResolvers(context);//初始化处理器异常解析器initRequestToViewNameTranslator(context);//初始化请求到视图名翻译器initViewResolvers(context);//初始化视图解析器initFlashMapManager(context);//初始化重定向数据管理器
}

五、SpringMVC中的适配器

        适配器模式:将一个系统的接口转换成另外一种形式,从而使原来不能直接调用的接口变得可以调用。使用适配器可以针对不容的handler类型找到不同的适配器来实现执行目标方法。

SpringMVC中有以下几种适配器:

1、继承Controller方式所使用的适配器:SimpleControllerHandlerAdapter

2、 HTTP请求处理器适配器:HttpRequestHandlerAdapter

3、注解方式(@Controller)的处理器适配器:RequestMappingHandlerAdapter

适配器模式应用场景

1.   Mybatis多种日志框架的整合(logback、log4j)

2.   SpringMVC适配器模式

3.   新老版本的兼容问题

适配器模式源码分析

1.使用getHandlerAdapter获取对应的hanlder的具体HandlerAdapter2.HandlerAdapter接口有如下的子 c处理请求适配器2.1继承Controller方式所使用的适配器:SimpleControllerHandlerAdapter2.2 HTTP请求处理器适配器:HttpRequestHandlerAdapter 2.3注解方式(@Controller)的处理器适配器:RequestMappingHandlerAdapter如果不采用适配器的话 :
If(hanlder instanceof Controller){// 执行Controller适配器
}If(hanlder instanceof  HttpControler){// 执行我们的HttpController
}If(hanlder instanceof  ServletControler){// 执行我们的HttpController
}If(hanlder instanceof  AnnotationControler){// 执行我们的AnnotationController
}

六、SpringMvc异步实现方式

异步支持需要注意的两个地方

* 1、config类中开启异步@EnableAsync

* 2、初始化类中 dynamic.setAsyncSupported(true);//开启springmvc异步

1、第一种方式:直接在接口上添加@Async注解来实现

@Async
public String getMember(){try {System.out.println("2、业务处理开始,线程名称"+Thread.currentThread().getContextClassLoader());Thread.sleep(3000);System.out.println("3、业务处理完毕,线程名称"+Thread.currentThread().getContextClassLoader());}catch (Exception e){e.printStackTrace();}return "member";
}

2、第二种方式:使用Callable类的方式

/*** 异步支持需要注意的两个地方* 1、config类中开启异步@EnableAsync* 2、初始化类中 dynamic.setAsyncSupported(true);//开启springmvc异步* Callable这种方式也是需要等业务线程处理完毕后,才会返回给客户端,为了避免等待时间,可以在客户端写一个定时器来查询处理结果*/
@RequestMapping("/asyncMember")
@ResponseBody
public Callable<String> asyncMember(){Callable<String> callable = new Callable<String>() {public String call() throws Exception {//耗时的时间都可以放在这个里面去处理String member = memberService.getMember();return member;}};return callable;
}

http://www.xdnf.cn/news/1254799.html

相关文章:

  • 前端页面直接生成PDF下载文件
  • “物联网+职业本科”:VR虚拟仿真实训室的发展前景
  • 物联网架构全解析:华为“1+2+1”与格行随身WiFi,技术如何定义未来生活?
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的微商产品经营策略研究
  • 技术优势铸就行业标杆:物联网边缘计算网关凭何引领智能变革?
  • 008 前端vue
  • Spring AOP动态代理核心原理深度解析 - 图解+实战揭秘Java代理设计模式
  • RabbitMQ-日常运维命令
  • 嵌入式硬件中MOSFET基本原理与实现
  • python函数--python010
  • Redis中间件(三):Redis存储原理与数据模型
  • 小红书开源多模态视觉语言模型DOTS-VLM1
  • ubuntu 2024 安装拼音输入法
  • VC6800智能相机:赋能智能制造,开启AI视觉新纪元
  • 【关于Java 8 的新特性】
  • 语言模型(LM):n-gram模型原理与困惑度(Perplexity)计算详解
  • 38.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--扩展功能--增加日志记录器
  • 嵌入式C语言编程:策略模式、状态模式和状态机的应用
  • 首个!3D空间推理框架3D-R1:融合强化学习、推理链、动态视角,实现7大任务SOTA!
  • LabVIEW注册表操作
  • 如何在 VS Code 中进行 `cherry-pick`
  • rebase 和pull的通俗区别是什么
  • TSMaster-C小程序使用
  • UE5多人MOBA+GAS 39、制作角色上半身UI
  • 主流小程序 SaaS 平台测评,2025年小程序开发避坑指南
  • 基于 Altium Designer 的电路原理图学习记录
  • 小程序省市级联组件使用
  • 机器学习通关秘籍|Day 04:梯度下降的概念原理、手动实现梯度下降
  • Day 6: CNN卷积神经网络 - 计算机视觉的核心引擎
  • Android 之 Kotlin 扩展库KTX