SpringMVC的执行流程

SpringMVC的执行流程

  1. 用户点击某个请求路径,发起一个request请求,此请求会被前端控制器处理。
  2. 前端控制器请求处理器映射器去查找Handler。可以是基于注解的、基于XML配置的或者基于Java配置的。
  3. 处理器映射器根据配置找到相应的Handler(可能包含若干个Interceptor拦截器),返回给前端控制器。
  4. 前端控制器请求处理器适配器去执行相应的Handler处理器(常称为Controller)。
  5. 处理器适配器执行Handler处理器。
  6. Handler处理器执行完毕之后会返回给处理器适配器一个ModelAndView对象(SpringMVC底层对象,包括Model数据模型和View视图信息)。
  7. 处理器适配器接收到Handler处理器返回的ModelAndView后,将其返回给前端控制器。
  8. 前端控制器接收到ModelAndView后,会请求视图解析器(ViewResolver)对视图进行解析。
  9. 视图解析器根据View信息匹配到相应的视图结果,反馈给前端控制器。
  10. 前端控制器收到View具体视图后,进行视图渲染,将Model中的模型数据填充到View视图中的request域,生成最终的视图(View)。
    前端控制器向用户返回请求结果。
处理器映射器根据配置找到相应的Handler(可能包含若干个Interceptor拦截器),返回给前端控制器

在Spring MVC中,处理器映射器(HandlerMapping)负责根据HTTP请求找到相应的处理器(Handler)。处理器通常是一个控制器方法。处理器映射器通过不同的策略来查找处理器,这些策略可以是基于注解的、基于XML配置的或者基于Java配置的。

以下是一些常见的根据什么查找处理器的例子:

  1. 基于注解的映射

    • @RequestMapping:这是最常用的注解,可以直接标注在控制器类或方法上。例如,如果一个控制器方法被标注为@RequestMapping("/hello"),那么当接收到路径为/hello的请求时,这个方法就会被调用。
    • @GetMapping@PostMapping等:这些是@RequestMapping的特定类型,用于处理特定HTTP方法的请求。
  2. 基于XML配置的映射

    • 在Spring的XML配置文件中,可以使用<bean>元素定义一个处理器映射,并通过<property>元素设置其属性,如handler-mappinginterceptors
    • 使用SimpleUrlHandlerMappingBeanNameUrlHandlerMapping等具体的处理器映射实现类来配置URL到处理器的映射关系。
  3. 基于Java配置的映射

    • 在Java配置类中,可以使用@EnableWebMvc注解启用Spring MVC的自动配置功能,然后通过@Configuration@Bean注解定义处理器映射。
    • 使用RequestMappingHandlerMapping作为处理器映射的实现类,并配置其属性。

无论使用哪种方式,处理器映射器都会根据请求的URL和HTTP方法找到对应的处理器。如果有多个拦截器(Interceptor)配置在处理器上,它们将在处理器执行前后按照配置的顺序被调用。

最终,前端控制器(DispatcherServlet)会接收到处理器映射器返回的处理器(可能包含若干个拦截器),然后继续后续的请求处理流程。

Spring 事务传播行为

Spring 事务传播行为定义了当一个事务方法被另一个事务方法调用时,应该如何处理事务。以下是 Spring 事务传播行为的详细介绍及各自举例说明:

  1. REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是最常见的传播行为,适用于大多数业务方法。

    • 举例 :在一个Service类中,有一个方法A调用另一个方法B,A和B都使用@Transactional注解,并且没有指定传播行为。这时,B会加入到A的事务中,或者如果A没有事务,B会创建一个新的事务。
  2. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。这种传播行为适用于对事务要求不严格的读操作。

    • 举例 :如果方法A在事务中调用了方法B,但B使用了@Transactional(propagation = Propagation.SUPPORTS)注解,那么B将在A的事务中运行,如果A没有事务,B将以非事务方式运行。
  3. MANDATORY:使用当前的事务,如果当前没有事务,则抛出异常。它强制要求必须在一个已经存在的事务中执行。

    • 举例 :如果方法A没有事务,而方法B使用了@Transactional(propagation = Propagation.MANDATORY)注解,那么调用B时会抛出异常。
  4. REQUIRES_NEW:创建一个新的事务,并且暂停当前事务(如果存在)。新事务完成后,原始事务才能继续执行。这种传播行为通常用于需要独立事务的场景。

    • 举例 :方法A在事务中调用了方法B,但B使用了@Transactional(propagation = Propagation.REQUIRES_NEW)注解,那么B将创建一个新的事务,而A的事务会被暂停,直到B的事务完成。
  5. NOT_SUPPORTED:以非事务方式执行操作,如果存在事务,就把当前事务挂起。通常用于需要在无事务状态下运行的批处理操作。

    • 举例 :如果方法A在事务中调用了方法B,但B使用了@Transactional(propagation = Propagation.NOT_SUPPORTED)注解,那么B将以非事务方式运行,同时A的事务会被挂起。
  6. NEVER:以非事务方式执行,如果存在事务,则抛出异常。它确保操作不会在事务中被执行。

    • 举例 :如果方法A在事务中调用了方法B,但B使用了@Transactional(propagation = Propagation.NEVER)注解,那么调用B时会抛出异常。
  7. NESTED:如果当前存在事务,则在嵌套事务内执行。如果没有活动事务,则与PROPAGATION_REQUIRED类似。它允许你在一个现有的事务中开启新的"事务",以便能够在出现异常时仅回滚部分操作。

    • 举例 :方法A在事务中调用了方法B,B使用了@Transactional(propagation = Propagation.NESTED)注解,那么B将在A的事务中开启一个嵌套事务。如果B中发生异常并标记为回滚,只有B的更改会被回滚,而A的事务仍然可以继续。

了解这些传播行为对于正确配置和管理Spring中的事务非常重要。通过合理地使用这些传播行为,可以确保业务逻辑的正确执行,同时避免事务相关的常见问题,如死锁和不一致的数据状态。在实际开发中,应根据具体的业务需求和场景选择合适的传播行为来优化事务管理。

相关推荐
快乐就好ya39 分钟前
Java多线程
java·开发语言
IT学长编程43 分钟前
计算机毕业设计 二手图书交易系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·二手图书交易系统
CS_GaoMing1 小时前
Centos7 JDK 多版本管理与 Maven 构建问题和注意!
java·开发语言·maven·centos7·java多版本
艾伦~耶格尔2 小时前
Spring Boot 三层架构开发模式入门
java·spring boot·后端·架构·三层架构
man20172 小时前
基于spring boot的篮球论坛系统
java·spring boot·后端
2401_858120532 小时前
Spring Boot框架下的大学生就业招聘平台
java·开发语言
S hh2 小时前
【Linux】进程地址空间
java·linux·运维·服务器·学习
转调2 小时前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
Java探秘者2 小时前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
攸攸太上2 小时前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway