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

springboot单体项目的执行流程

首先就是启动springboot项目,即执行主函数,这个主函数的类通常带有SpingBootApplication注解,类中的main方法就是程序的入口。

启动主函数后,SpringBoot会按特定顺序加载配置文件,如application.properties或application.yml,这两种格式的文件都行,还能根据不同的环境加载不同的加载文件,如生产环境,测试环境等。配置文件里一般包含数据库连接的信息,服务端接口,日志级别等。

接着main函数中的run方法会创建一个Spring容器负责管理项目中的Bean,具体过程就是在调用SpingApplication.run方法时,会先创建一个SpringApplication实例,该实例会进行如下工作:

   1.推断应用类型,判断时Web应用还是非Web应用。

   2.查找并加载初始化器(ApplicationContextInitializer),这些初始化器可以在                                  ApplicationContext(应用上下文,是一个管理Spring应用中各种组件如Bean,配置信息,时间等的高级容器)刷新之前进行自定义配置。

  3.查找并加载监听器,监听器会监听应用启动过程中的各种时间,如应用启动,上下文刷新等。

  4.推断主应用类,即包含main方法的类

然后SpringApplition实例会根据应用类型创建相应的ApplicationContext实例。

接下来就是加载Bean定义,ApplicationContext会加载所有的Bean定义,这些Bean定义可以来自多个地方:

   1.通过@ComponentScan扫描指定路径下的带有@Component,@Service,@Repository,          @Controller等注解的类

   2.@Configuration注解的配置类中使用@Bean注解定义的类

 接着就是在Applicationtext刷新的过程中,会根据Bean定义创建Bean实例,并进行依赖注入和生命周期管理。Spring容器会确保Bean的单例性(默认情况下,也可以指定为多例),并处理Bean的初始化和销毁方法。

在Sping容器和Bean加载完成后,还会启动服务器,执行命令运行器和应用启动运行器(对实现了CommandLineRunner或ApplicationRunner接口的Bean在应用启动后执行一些初始化操作),最后发布应用启动完成事件。

讲完了springboot的启动后下面就是交互过程了。

客户端发起请求,这个请求是HTTP请求,它包括如下方法:

  1.请求方法:常见的有GET(用于获取资源),POST(用于提交数据),PUT(用于更新资源),DELETE(用于更新资源),DELETE(用于删除资源)等

  2.请求URL:指明要访问的资源地址

  3.请求头:携带关于请求的额外信息,包含很多信息,如客户端类型,请求体的数据格式,请求发送的日期时间,身份验证(例如把token放到请求头中)等等

  4.请求体:POST,PUT等方法可能会携带请求体,用于传递数据,数据格式可以是JSON,XML等

  接着请求到达了SpringBoot应用所监听的端口,在请求到达之前,服务器一直在监听该端口,端口一般是8080。

嵌入式服务器接收到请求后,会进行如下操作:

  1.将原始的HTTP请求封装成HttpServletRequest对象,该对象提供了一系列方法用于获取请求的各种信息,如请求方法,请求URL,请求头,请求体等。

  2.同时创建一个HttpServletResponse响应对象,用于后续后端向前端返回消息

请求在到达DispatcherServlet之前,会经过一系列过滤器,过滤器可以实现编码转换,请求日志,权限验证等功能,通过实现Filter接口来定义过滤器。

DispatcherServlet作为SpringMVC的核心调度器,继承自HttpServlet,在SpringBoot启动时自动配置和初始化,接受经过过滤器链处理后的请求。

在查找处理器(三层架构中的controller)之前,DispatcherServlet会进行一些预处理操作:

  1.检查请求是否为文件上传请求,若为文件上传请求,则将请求包装成MultipartHttpServletRequest。

  2.根据请求的Accept头确定合适的消息转换器,用于后续处理响应数据的格式转换

(这里的Accept头是HTTP请求头中的一个字段,他用于告知服务器客户端能够接受的响应内容类型)

HandlerMapping根据请求的URL和请求方法,从被@Controller或@RestController注解标记的类中查找对应的处理器方法。常见的HandlerMapping实现是RequestMappingHandlerMapping,它依据@RequestMapping,@GetMappingdeng等注解来匹配处理器方法。

在确定请求对应的处理器之后,调用处理器方法之前,会执行拦截器的preHandle方法。拦截器是SpringMVC提供的功能,可用于对处理器方法进行增强,如权限验证,日志记录,性能监控等。

示例:

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 权限验证if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/login");return false;}// 记录请求开始时间request.setAttribute("startTime", System.currentTimeMillis());return true;}
}

若拦截器的preHandle方法返回true,HandlerAdapter会将请求中的参数(如URL参数,请求体参数等)绑定到处理器方法的参数上,并调用处理器方法。在这个过程中,控制器可能会调用服务层的方法来处理业务逻辑。

服务层主要负责处理业务规则,数据访问和事务管理等操作。控制器调用服务层的方法,服务层再调用数据访问层(DAO)来与数据库或其他数据源进行交互。

数据访问层负责与底层数据源进行交互,执行数据的增删改查,通常用mybatis或者mybatisplus进行实现。

处理器方法执行完成后,在视图渲染之前,会执行拦截器的postHandle方法。此方法可用于对处理器方法的执行结果进行修改或补充。

处理器方法处理完业务逻辑后,返回一个结果。结果可以是视图名称(用于视图渲染),也可以是数据对象(如JSON,XML等)。如果使用@RequestController注解,默认会将返回的对象转换为JSON格式返回给客户端。

若处理器方法返回的是视图名称,DispatcherServlet会使用ViewResolver解析视图,将模型数据传递给视图模版进行渲染。

视图模板将模型数据和视图模版合并,生成最终的HTML页面。(如果有)

在整个请求处理完成后,包括视图渲染完成,会执行拦截器的afterComletion方法。此方法主要用于进行资源清理操作,如关闭数据库连接,记录请求处理的总时长等。

处理器方法返回的结果(视图或数据)被封装到HttpServletResponse对象中,DispatcherServlet设置响应的状态码,响应头和响应体。

响应在返回客户端之前,再次经过过滤器,过滤器可对响应进行后置处理,如添加响应头,压缩响应数据等。

嵌入式服务器将HttpServletResponse对象中的响应数据返回给客户端,客户端根据响应内容进行相应处理。

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

相关文章:

  • LFU算法解析
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】4.5 清洗流程自动化(存储过程/定时任务)
  • 【中间件】brpc_基础_单例
  • FreeRTOS学习系列·二值信号量
  • Linux查询日志常用命令
  • 解锁现代健康密码:科学养生新主张
  • 基于PLC的换热器温度控制系统设计
  • 状态模式(State Pattern)
  • 电子商务商家后台运营专员模板
  • C++ 中二级指针的正确释放方法
  • 【KWDB 创作者计划】_Ubuntu 22.04系统KWDB数据库安装部署使用教程
  • Qt中的UIC
  • Amazon Bedrock Converse API:开启对话式AI新体验
  • Qt开发:容器组控件的介绍和使用
  • 20、数据可视化:魔镜报表——React 19 图表集成
  • 408考研逐题详解:2009年第8题
  • Java后端程序员学习前端之CSS
  • Python matplotlib 成功使用SimHei 中文字体
  • 详解RabbitMQ工作模式之发布订阅模式
  • 基于C++实现的深度学习(cnn/svm)分类器Demo
  • Baklib知识中台:智能服务架构新实践
  • 【算法学习】递归、搜索与回溯算法(一)
  • python函数复习(形参实参,收集参数,关键字参数)
  • uniapp中用canvas绘制简单柱形图,小容量,不用插件——简单使用canvas
  • QT 在圆的边界画出圆
  • IP属地是我的定位吗?——解析两者区别
  • Python异步编程入门:从同步到异步的思维转变
  • VBA信息获取与处理专题五:VBA利用CDO发送电子邮件
  • 【外围电路】按键电路设计外接信号输入设计
  • Go小技巧易错点100例(二十九)