前言
你们用过Spring-mvc 吗,一条Http 请求的只修改流程是怎样的,Springboot项目的自动装配是怎样的,存储的orm 框架Mybatis 你们用到了吗,他的一二级缓存是怎样的。本文重点对面试的问题进行介绍,祝愿每位程序员都能顺利上岸!!!
一、你们项目有使用过Spring-mvc 架构吗
Spring -mvc 分层架构,可以使得代码的层次变得更加的清晰;M(model):作为数据模型层,V(view)页面视图层,C(控制器)请求接入;三层架构 C层加入请求并处理,将得到的结果封装为Model ,然后交由View 进行数据的加载,最终返回要展示的界面;
1.1 前后端一起 请求的执行流程:
- 前端控制器: 方法请求的入口,相当于一个路由
- 处理器映射器 ,找到对应的类(返回一个chain 链路,如果有拦截器会在这里包装返回)
- 处理适配器,对入参和返回值 进行处理
- 通过视图解析器,将逻辑视图转为真正的视图(jsp 中一些表达式值的填充)
① 用户发送出请求到前端控制器DispatcherServlet
② DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
③ HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet.
④ DispatcherServlet调用HandlerAdapter(处理器适配器)
⑤ HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
⑥ Controller执行完成返回ModelAndView对象
⑦ HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet
⑧ DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)
⑨ ViewReslover解析后返回具体View(视图)
⑩ DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)
① DispatcherServlet响应用户
1.2 前后端分离 请求的执行流程:
① 用户发送出请求到前端控制器DispatcherServlet
② DispatcherServlet收到请求调用HandlerMapping(处理器映射器)
③ HandlerMapping找到具体的处理器,生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet.
④ DispatcherServlet调用HandlerAdapter(处理器适配器)
⑤ HandlerAdapter经过适配调用具体的处理器(Handler/Controller)
⑥ 方法上添加了@ResponseBody
⑦ 通过HttpMessageConverter来返回结果转换为JSON并响应
二、你们项目中使用Mybatis 框架吗
Mybatis 用作ORM框架,将java 对象同数据库中的数据进行转换。
2.1 Mybatis 的执行流程
Spring 中主要通过 SqlSessionFactoryBuilder().build(reader) 方法完成 事务管理器,数据源以及sql 语句的解析和绑定,并将解析好的sql 放入到map 中;Spring 启动时会为Mapper 接口层生成代理对象,当使用代理对象进行方法的调用,执行时通过key(方法名) 获取具体的sql 语句交由执行器执行,然后返回执行结果,解析过程可以参考:Spring-Mybatis源码解析–Mybatis配置文件解析
① 读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
② 构造会话工厂SqlSessionFactory
③ 会话工厂创建SqlSession对象(包含了执行SQL语句的所有方法)
④ 操作数据库的接口,Executor执行器,同时负责查询缓存的维护
⑤ Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
⑥ 输入参数映射
⑦ 输出结果映射
2.2 Mybatis 是否支持延迟(按需)加载
延迟加载的意思是:就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。Mybatis支持一对一关联对象和一对多关联集合对象的延迟加载。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=truelfalse,默认是关闭的。
2.2.1 一个用户下多个订单的查询
场景: Mybatis 以订单场景为例,我们向通过一条sql ,查出一个用户下的多个订单,进行数据返回;但是有时我们可能只有到用户的信息,是否能需要改用户下的订单信息时在进行订单的数据查询呢,Mybatis 提供了Lazy 可以来实现。
对应sql语句:
方法的调用:
此时在第一次查询用户的信息,同时也会执行对用户下订单查询的sql ;
2.2.2 使用lazy 进行延迟加载:
使用后的效果:
2.2.3 你知道lazy 的实现原理吗
只查询用户信息时,订单的列表字段会被复制为null,当调用订单信息的方法时,实际上是通过代理对象实现的
- 使用CGLIB创建目标对象的代理对象;
- 当调用目标方法user.getOrderlist()时,进入拦截器invoke方法,发现user.getOrderlist()是nul值,执行sql查询order列表
- 把order查询上来,然后调用user.setOrderList(ListorderList),接着完成user.getOrderlist()方法的调用;
2.3你知道 Mybatis 的一级缓存,二级缓存吗
2.3.1 一级缓存:
一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当Session进行flush或close之后,该Session中的所有Cache就将清空,默认打开一级缓存。
2.3.2 二级缓存:
二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于SQLsession,默认也是采用 PerpetualCacheHashMap 存储。二级缓存默认关闭。
2.3.3 Mybatis的二级缓存什么时候会清理缓存中的数据
当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了新增、修改、删除操作后,默认该作用域下所有 select 中的缓存将被 clear。
三、你们项目中使用Spring-boot 吗,你知道它的自动装配吗
spring-boot 提供了类的自动装配机制,可以使的开发人员只进行相关的参数定义,即可方便的使用各种bean。
3.1 你知道SpringBoot 的自动装配吗
在springboot 项目启动类上@SpringBootApplication 中有个@EnableAutoConfiquration:它是SpringBoot实现自动化配置的核心注解。
通过自动装配的注解,去加载Spring-factories
并通过@Condition 条件注解判断是否需要加载这个类
- 在Spring Boot项目中的引导类上有一个注解@SpringBootApplication,这个注解是对三个注解进行了封装,分别是:
@SpringBootConfiquration
@EnableAutoConfiquration
@Componentscan - 其中@EnableAutoConfiquration是实现自动化配置的核心注解。该注解通过@lmport注解导入对应的配置选择器。内部就是读取了该项目和该项目引用的Jar包的的classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。 在这些配置类中所定义的Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。
- 条件判断会有像@ConditionalOnClass这样的注解,判断是否有对应的class文件,如果有则加载该类,把这个配置类的所有的Bean放入spring容器中使用。
3.2 Spring 框架常见的注解都有哪些:
3.2.1 Spring 中的常见注解:
3.2.2 Spring-mvc 中的常见注解:
3.2.3 Spring-boot 中的常见注解:
总结
本文对Spring-Mvc 的执行过程,Mybatis Orm 框架,以及对Springboot 的自动装配常见面试内容进行的整理。