Spring MVC的工作流程

Spring MVC的工作流程
  1. 客户端向服务端发送一次请求,这个请求会先到前端控制器DispacherServlet
  2. DispacherServlet接收到请求后会调用HandlerMapping处理器映射器——该请求由哪个Controller来处理
  3. DispacherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该去执行哪个Controller(这个存在的意义是有不同的Controller类型)
  4. DispacherServlet将ModelAndView交给视图解析器解析,然后返回真正的视图。
  5. DispacherServlet将模型数据填充到视图中。
  6. DispacherServlet将结果返回给客户端。

二、SpringMVC Restful风格的接口的流程是怎么样的?

  • 请求进入

    • 浏览器发请求,首先到DispatcherServlet(前端控制器)。

    • 👉 相当于“总调度”。

  • 找到处理器

    • DispatcherServlet 问HandlerMapping:“这个请求该交给谁处理?”

    • HandlerMapping 返回对应的Controller

  • 执行 Controller

    • DispatcherServlet 交给HandlerAdapter去执行 Controller 方法。

    • 👉 Controller 就是你写的@GetMapping("/user")这种方法。

  • 处理返回值

    • 如果 Controller 方法上有@ResponseBody,返回对象就要转成 JSON。

    • 过程:

      • Spring 用HttpMessageConverter(默认 Jackson)把对象序列化成 JSON。

      • 写到响应的OutputStream里。

  • 响应返回给浏览器

    • 这时 JSON 已经写进了 HTTP 响应体,直接返回给客户端。

    • 👉 如果方法返回ModelAndView,才会走视图解析,这里返回的是 JSON,所以不需要。


Spring Boot

一、介绍一下Spring Boot,有哪些优点

  • 自动配置:内置了大量常用场景的配置,开发者只需要少量配置。比如加上spring-boot-starter-web,就能快速构建 Web 应用。
  • starter机制:提供一系列start依赖包,整合第三方框架很方便,spring-boot-starter-redis。
  • 内嵌服务器:传统的方式写完代码后,要把项目打包成WAR包,还要准备一个外部的应用服务器(如Tomcat),把war包放到服务器的webapps目录下,重启tomcat才能跑。但在SpringBoot中直接内嵌了服务器,只需要打包一个jar包,然后直接命令执行,会自动把内嵌的Tomcat启动起来。
  • 约定优于配置:提供了一套合理的默认约定,若不写配置就用默认值,若有特殊需求,也可以再覆盖配置。
  • 依赖管理:提供官方Start POM,一行依赖搞定一整套功能,避免版本冲突。

二、Spring Boot自动配置原理

传统Spring需要写一堆XML或配置,如web项目要自己配置DispatcherServlet、ViewResolver、消息转换器,数据库要自己配置dataSource等。那SpringBoot的最大特点就是这些常见配置不需要你写,自动帮你配好。

1

2

3

4

5

6

@SpringBootApplication

publicclassDemoApplication {

publicstaticvoidmain(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}

1、 启动类上有一个@SpringBootApplication注解,这个注解里面包含@EnableAutoConfiguration。

2、SpringFactories 机制:Spring Boot 在自己的 jar 包里,放了一个文件:
META-INF/spring.factories。如果启用了自动配置,请把这些类也加载进来。

1

2

3

4

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\

...

3、条件注解:比如DataSourceAutoConfiguration

1

2

3

4

5

6

@Configuration

@ConditionalOnClass(DataSource.class)// classpath 里有 DataSource 才生效

@ConditionalOnMissingBean(DataSource.class)// 容器里没有你自己定义的 DataSource 才生效

publicclassDataSourceAutoConfiguration {

// 自动帮你注册一个 DataSource bean

}

  • 你引入了spring-boot-starter-jdbc→ classpath 里就有DataSource→ 自动配置生效 ✅
  • 如果你自己写了一个@Bean DataSource→ Boot 就尊重你写的,不去覆盖 ❌

三、Spring Boot启动原理

1

2

3

4

5

6

@SpringBootApplication

publicclassDemoApplication {

publicstaticvoidmain(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}

  1. 创建一个SpringApplication对象,判断应用类型(普通应用/servlet Web应用),加载ApplicationContext类型。
  2. 读取配置:去application.yml/application.properties里读配置。把数据库地址、端口号、日志级别等全都存好。
  3. 加载Bean定义:你写的类上有@Component@Service@Repository@Controller,Spring 都会扫描到。Spring Boot 还会根据依赖(比如spring-boot-starter-web)自动帮你装好“常用机器”(Tomcat、Jackson、异常处理器等)。
  4. 创建Bean+依赖注入:Spring 会 new 出所有对象(实例化),Spring 会 new 出所有对象(实例化)。
  5. 启动内嵌服务器:若是Web项目,会自动帮你把Tomcat启动起来,端口默认8080.注册好DispatcherServlet,专门接收用户请求并分发给Controller。
  6. 应用就绪。

四、对Spring Cloud的了解

1、概念

微服务是一种架构风格,代表着一种通过将应用程序拆分成小型、独立的功能模块的开发方式。每个模块(服务)实现独立的业务功能不限语言,服务之间通过轻量级的通信机制,如HTTP/REST或消息队列进行交互。微服务架构的核心思想是:解耦应用程序,提升灵活性和维护性。

微服务的优点:

  • 模块独立解耦
  • 独立部署、快速迭代(如果改动了某个微服务,不需要重启整体的项目)
  • 灵活技术栈
  • 高扩展性
  • 容错性好

缺点:分布式系统复杂性(服务器成本,开发人员成,运维成本增加)

2、Spring Cloud介绍&搭建

  • 服务治理:通过注册中心(如Nacos)实现服务的注册、发现与剔除,并依靠心跳机制保证实例健康可用。
  • 服务间调用:通过声明式调用工具(如Feign)简化服务之间的通信逻辑,实现透明化的远程调用。
  • 统一入口:利用Gateway作为流量入口,对外提供统一的访问网关,实现路由转发与权限控制。
  • 容错与限流:引入Sentinel进行熔断、限流与降级,提升系统在异常情况下的自我保护能力。
  • 问题排查:借助SkyWalking等链路追踪工具,监控请求在各微服务间的调用路径,快速定位故障。
  • 分布式事务:通过Seata协调跨服务的全局事务,确保在多服务协同操作时的数据一致性。

引入Spring Cloud pom

<dependencyManagement> <dependencies> <!-- Spring Cloud 版本依赖(根据 Boot 版本来选) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.8</version> <!-- 举例,实际要看Boot版本 --> <type>pom</type> <scope>import</scope> </dependency> <!-- Spring Cloud Alibaba 版本依赖(Nacos, Sentinel, Seata 等) --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.5.0</version> <!-- 要和上面保持兼容 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

3、整合Nacos注册中心进行服务发现

假设现在有个小demo,有两个功能(下单、库存),这时候下单服务是通过用HTTP的方式来调用库存服务的接口。假设这个库存服务进行了集群,就会有很多的地址和端口,如果都需要自己去管理的话会非常麻烦。这时候就可以用nacos来帮我们解决这个问题。

(1)安装nacos服务:https://nacos.io/download/nacos-server/?spm=5238cd80.c984973.0.0.6be14023Dk5qSI

(2)打开安装好的文件夹conf,application.properties文件,因为nacos里面有很多数据要持久化,所以我们要连接数据库,根据原本的配置去创建一个'nacos'数据库(记得数据库名字要和配置里面的一致)。把安装包的mysql-schema.sql文件在新建的这个数据库运行一下,就会产生很多个数据表。

(3)打开安装包的bin,里面的startup.cmd文件(因为默认是集群方式启动),把'cluster'改为'standalone'(set MODE = 'standalone')。双击启动即可,端口是8848。接下来可以通过localhost:8848/nacos启动,就可以打开nacos的控制面板。

(4)引入具体的Spring Cloud组件

<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>

(5)在两个服务的启动类上加入@EnableDiscoveryClient, 表示当前应用启用了nacos的服务。

(6)在两个服务的application.yml的文件中修改配置。

spring: application: name: order-server cloud: nacos: discovery: server:addr: 127.0.0.1:8848

(7)启动项目,在nacos控制面板就可以看到两个服务。

(8)服务发现集成Spring Cloud Loadbalancer组件(放在需要远程调用的消费者端order)。然后再OrderApplication中的public RestTemplate上加一个@LoadBalanced注解。然后在OrderController就可以通过服务名访问了。

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>

//原来是写死的 http://localhost:8082/xxx,现在换成 服务名调用: