SSM框架执行流程及底层源码讲解【本文持续更新...】
SSM框架执行流程及底层源码讲解
---- 本篇文章主要讲解市面流行的项目框架:SpringMVC+Spring+MyBatis (简称SSM) 的执行流程以及执行过程中各个关键技术的底层实现原理。(博主接触java编程语言近两年时间,一直对框架实现原理懵懵懂懂,终于下定决心研究一番底层源码,本文为原创作品,原文出自本人hexo+github个人博客,地址: https:lhbit.top 懒得再重写一遍,直接贴过来算了,如有讲解不周之处还望见谅,如有异议或不同见解,请评论区留言,谢谢!)
SpringMVC框架
简单介绍:
----SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求。
清晰的角色划分
-
前端控制器(DispatcherServlet)
-
处理器映射器(HandlerMapping)
-
处理器适配器(HandlerAdapter)
-
视图解析器(ViewResolver)
-
处理器或页面控制器(Controller)
-
验证器( Validator)
-
命令对象(Command 请求参数绑定到的对象就叫命令对象)
-
表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)
单个业务执行流程:
-
tomcat启动: 加载应用的web.xml
-
实例化并初始化Servlet
-
加载spring.xml配置文件创建spring容器,根据配置初始化容器中的对象。
-
浏览器客户端发送请求,例如Hello()
-
请求到达前端控制器:DispatcherServlet
-
前端控制器截取动作名称Hello(),并从@RequestMapping中找具体的Hello方法
-
找到后,执行控制器中的方法
-
假如方法有返回值,则根据返回值通过InternalResourceViewResolver找到相应的结果视图
-
响应给浏览器,展示结果
详细执行流程:
-
前端页面发送Request请求给前端控制器:DispatcherServlet
-
DispatcherServlet 请求查找Handler 到处理器映射器HandlerMapping
-
HandlerMapping 返回一个执行链:HandlerExecutionChain{ HandlerInterceptor1 HandlerInterceptor2 HandlerInterceptor3 ...... Handler } 给前端控制器DispatcherServlet
-
前端控制器请求适配器HandlerAdapter执行
-
处理器Controller执行逻辑,调用业务层(Service层),业务层调用持久层(DAO)层,然后逐层返回到Controller
-
Controller 返回 ModelAndView 给适配器
-
适配器返回ModelAndView 给 DispatcherServlet
-
DispatcherServlet请求视图解析器(ViewResolver)进行视图解析,
-
视图解析器返回View给DispatcherServlet
-
进行视图渲染,将模型数据填充到request域
-
DispatcherServlet给前台页面response响应
Spring框架(程序员的春天)
简单介绍:
---- Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。
---- 先上两张Spring的类结构图
spring框架执行流程
---- 使用spring配置,需要在web.xml中配置一个spring的监听器和启动参数(context-param),如下:
<!-- 配置加载类路径的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!-- 配置监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
---- web容器启动时,下面为spring加载执行步骤:
-
执行web.xml中的ContextLoaderListener监听器
-
初始化ContextLoaderListener中的contextInitialized方法
-
contextInitialized方法中调用父类(ContextLoader)的initWebApplicationContext方法
-
initWebApplicationContext方法中执行了三个任务
-
创建WebApplicationContext容器
-
加载context-param中配置的spring配置文件
-
初始化配置文件及创建配置文件中的bean
-
---- 最后,当web容器停止时候会执行ContextLoaderListener的contextDestroyed方法销毁context容器
MyBatis框架
简单介绍:
---- MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis主要的类
-
Configuration MyBatis所有的配置信息都维持在Configuration对象之中。
-
SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话, 完成必要数据库增删改查功能
-
Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
-
StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
-
ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数,
-
ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
-
TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换
-
MappedStatement MappedStatement维护了一条<select|update|delete|insert>节点的封装,
-
SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回
-
BoundSql 表示动态生成的SQL语句以及相应的参数信息
以上几个类在SQL操作中都会涉及,在SQL操作中重点关注下SQL参数什么时候写入和结果集怎么转换为Java对象,这两个过程正好对应的类是PreparedStatementHandler和ResultSetHandler类。
Mybatis执行流程
---- 首先,SqlSessionFactory 会话工厂会加载 SqlMapConfig.xml 配置文件信息,然后生成一个可以与数据库交互的会话实例类 SqlSession,会话实例类 SqlSession 会根据 Mapper 配置文件中的 sql 配置,去执行相应的增删改查操作。这样,MyBatis 就实现了与数据库的交互功能。具体流程图如下:
---- 下面简单介绍总结各个组件的含义和功能:
Configuration.xml:该配置文件是MyBatis的全局配置文件,在这个文件中可以配置诸多项目,但是一般项目中,并不会配置太多内容,常用的内容是别名设置,拦截器设置等,至于环境设置与Mapper映射文件的注册会转移到Spring配置文件中(SSM整合之后),而其余大部分的配置项都采用默认的配置。
XMLConfigBuilder:该类是XML配置构建者类,是用来通过XML配置文件来构建Configuration对象实例,构建的过程就是解析Configuration.xml配置文件的过程,期间会将从配置文件中获取到的指定标签的值逐个添加到之前创建好的默认Configuration对象实例中。
Configuration:该类是MyBatis的配置类,创建这个类的目的就是为了使用其对象作为项目全局配置对象,这样通过配置文件配置的信息可以保存在这个配置对象中,而这个配置对象在创建好之后是保存在JVM的Heap内存中的,方便随时读取。不然每次需要配置信息的时候都要临时从磁盘配置文件中获取,代码复用性差的同时,也不利于开发。
SqlSessionFactoryBuilder:该类是SqlSessionFactory(会话工厂)的构建者类,之前描述的操作其实全是从这里面开启的,首先就是调用XMLConfigBuilder类的构造器来创建一个XML配置构建器对象,利用这个构建器对象来调用其解析方法parse()来完成Configuration对象的创建,之后以这个配置对象为参数调用会话工厂构建者类中的build(Configuration config)方法来完成会话工厂对象的构建。
SqlsessionFactory:该接口是会话工厂,是用来生产会话的工厂接口,DefaultSqlSessionFactory是其实现类,是真正生产会话的工厂类,这个类的实例的生命周期是全局的,它只会在首次调用时生成一个实例(单例模式),就一直存在直到服务器关闭。
openSession():在最后的build(Configuration config)方法中会返回一个DefaultSqlSessionFactory类的实例,这个类是MyBatis提供的默认会话工厂类,而我们使用的也正是这个类中的来openSession()方法来完成SqlSession对象的创建。
SqlSession:该接口是会话,是项目与数据库之间的会话,类似于客户端与服务器之间的会话(session),这个SqlSession的生命周期是方法级的,因为他是非线程安全的,针对每一次数据库访问都要创建一个SqlSession,获取到返回结果之后,这个SqlSession就会被废弃。这区别于SqlSessionFactory的生命周期。
Executor:执行器接口,SqlSession会话是面向程序员的,而内部真正执行数据库操作的却是Executor执行器,可以将Executor看作是面向MyBatis执行环境的,SqlSession就是门面货,Executor才是实干家。通过SqlSession产生的数据库操作,全部是通过调用Executor执行器来完成的。
StatementHandler:该类是Statement处理器,封装了Statement的各种数据库操作方法execute(),可见MyBatis其实就是将操作数据库的JDBC操作封装起来的一个框架,同时还实现了ORM罢了。
ResultSetHandler:结果集处理器,如果是查询操作,必定会有返回结果,针对返回结果的操作,就要使用ResultSetHandler来进行处理,这个是由StatementHandler来进行调用的。这个处理器的作用就是对返回结果进行处理。
- - - - - - - - - -暂时先写到这里,本文持续更新,未完待续.... - - - - - - - - - -
SSM 整合