面试经验总结——框架篇

148 阅读8分钟

1.springMvc的原理

问:什么是SpringMvc

答:通过DispatcherServlet将一对组件串联起来的Web框架,主要组件有DispatcherServlet,处理器映射,处理器(控制器),视图解析器,视图

问:为什么使用SpringMvc

答:传统的Servlet,每个请求都需要在web.xml中进行配置,请求一多开发量和耦合度非常恐怖,springMvc是一层封装,所有请求都由DispatcherServlet转发了,类似于JDBC和MyBatis的关系,本质上是对Servlet的封装,简化了开发步骤

问:主要组成部分

答:主要由以下接口组成

DispatcherServlet接口:负责转发请求,所有请求都会通过该接口统一分发。

HandlerMapping接口:用于将请求映射到对应的Controller

Controller接口:即Controller层,处理器,处理对应业务,处理完毕后,通过ModelAndView返回给DispatcherServlet控制器

ViewResolver接口:视图解析器,由Controller返回的view会在此匹配对应的视图

问:SpringMvc的运行原理

答:1.客户端发起请求,请求会被DispatcherServlet拦截

2.DispatcherServlet查询HandlerMapping,匹配对应的Controller(如果配置了注解扫描就会去扫描注解)

3.匹配后,找到对应的Controller,将请求提交给Controller

4.Controller进行业务逻辑处理后,返回ModelAndView到DispatcherServlet

5.DispatcherServlet查询一个或多个ViewResolver视图解析器,找到ModelAndView指定的view

6.视图负责将结果渲染到view

补充:DispatcherServlet的配置在web.xml中,同时要指定HanlderMapping的配置文件

问:注解是什么,常用的注解是什么

答:在applicationContext.xml中配置注解驱动与扫描路径,之后通过在类与变量上加注解便可注入与引用

常用注解:

1.Component:通用注解,用于注册一个类,不推荐

2.Controller:用于Controller层的注册

3.Service:用于Service层的注册

4.Repository:用于Dao层的注册

补充:以上注解均可用value属性指定bean名称,如果不指定bean,就以类名首字母小写后的名称作为bean名

问:Resource和Autowired的区别

答:都是用于bean的注入,都可以写在字段上和方法上,Autowired属于Spring,Resource属于J2E,Autowired按类型装配,Resource按名称装配

问:如何用注解配置映射,有哪些方式,参数的接收方式有哪些?

答:RequestMapping,PostMapping,GetMapping三种

参数接收方式:

(1)占位符URL,如“test/{id}“,使用PathVariable绑定指定参数,如@PathVariable("id")

(2)传统HttpServletRequest参数获取,@RequestParam("age")

(3)@CookieValue ( "hello" ),用于绑定Cookie的值

(4)@RequestHeader("host")绑定请求头元素,这个不区分大小写

补充:以上都可以不用单独指定名称,会按属性名进行匹配

问:RequestMapping标记的处理器方法支持的方法参数类型和返回类型

支持的方法参数类型:

(1)HttpServlet对象,包括HttpServletRequest 、HttpServletResponse 和HttpSession。Spring 自己的WebRequest 对象。InputStream 、OutputStream 、Reader 和Writer。@PathVariable 、@RequestParam 、@CookieValue 和@RequestHeader 标记的参数。@ModelAttribute 标记的参数。实体类。 可以用来接收上传的参数。Spring 封装的MultipartFile 。 用来接收上传文件的。Spring 封装的Errors 和BindingResult 对象。 这两个对象参数必须紧接在需要验证的实体对象参数之后,它里面包含了实体对象的验证结果。

(2)

  1. HttpServlet 对象,主要包括HttpServletRequest 、HttpServletResponse 和HttpSession 对象。 这些参数Spring 在调用处理器方法的时候会自动给它们赋值,所以当在处理器方法中需要使用到这些对象的时候,可以直接在方法上给定一个方法参数的申明,然后在方法体里面直接用就可以了。但是有一点需要注意的是在使用HttpSession 对象的时候,如果此时HttpSession 对象还没有建立起来的话就会有问题。

  2. Spring 自己的WebRequest 对象。 使用该对象可以访问到存放在HttpServletRequest 和HttpSession 中的属性值。

  3. InputStream 、OutputStream 、Reader 和Writer 。 InputStream 和Reader 是针对HttpServletRequest 而言的,可以从里面取数据;OutputStream 和Writer 是针对HttpServletResponse 而言的,可以往里面写数据。

  4. 使用@PathVariable 、@RequestParam 、@CookieValue 和@RequestHeader 标记的参数。

  5. 使用@ModelAttribute 标记的参数。

  6. java.util.Map 、Spring 封装的Model 和ModelMap 。 这些都可以用来封装模型数据,用来给视图做展示。

  7. 实体类。 可以用来接收上传的参数。

  8. Spring 封装的MultipartFile 。 用来接收上传文件的。

  9. Spring 封装的Errors 和BindingResult 对象。 这两个对象参数必须紧接在需要验证的实体对象参数之后,它里面包含了实体对象的验证结果。

支持的返回类型:

  1. ModelAndView 对象。

  2. 一个模型对象,这主要包括Spring 封装好的Model 和ModelMap ,以及java.util.Map ,当没有视图返回的时候视图名称将由RequestToViewNameTranslator 来决定。

  3. 一个View 对象。这个时候如果在渲染视图的过程中模型的话就可以给处理器方法定义一个模型参数,然后在方法体里面往模型中添加值。

  4. 一个String 字符串。这往往代表的是一个视图名称。这个时候如果需要在渲染视图的过程中需要模型的话就可以给处理器方法一个模型参数,然后在方法体里面往模型中添加值就可以了。

  5. 返回值是void 。这种情况一般是我们直接把返回结果写到HttpServletResponse 中了,如果没有写的话,那么Spring 将会利用RequestToViewNameTranslator 来返回一个对应的视图名称。如果视图中需要模型的话,处理方法与返回字符串的情况相同。

  6. 如果处理器方法被注解@ResponseBody 标记的话,那么处理器方法的任何返回类型都会通过HttpMessageConverters 转换之后写到HttpServletResponse 中,而不会像上面的那些情况一样当做视图或者模型来处理。

  7. 除以上几种情况之外的其他任何返回类型都会被当做模型中的一个属性来处理,而返回的视图还是由RequestToViewNameTranslator 来决定,添加到模型中的属性名称可以在该方法上用@ModelAttribute(“attributeName”) 来定义,否则将使用返回类型的类名称的首字母小写形式来表示。使用@ModelAttribute 标记的方法会在@RequestMapping 标记的方法执行之前执行。

2.SpringAOP的原理

问:什么是AOP

答:面向切面编程,面向对象编程的补充,可以降低系统耦合度,提升开发效率与可重用性

问:什么是springAOP,和AspectJ的区别

答:springAOP属于动态代理的AOP,不会修改字节码,而是直接生成一个AOP对象,包含原对象的全部方法,并在特定切口进行增强,并回调原对象的方法,SpringAOP实际上动态生成了一个代理类,分为JDK动态代理与CGLIB代理两类,如果目标类实现了接口,则采用JDK动态代理,反之则使用CGLIB代理;与之相对应的是AspectJ的静态代理,会直接在编译阶段修改字节码,运行时就是修改过的对象方法

问:什么时候需要AOP

答:通俗的讲,当很多方法要调用同一段代码块时,就需要AOP了;通常用于日志记录,事务管理,异常处理,性能统计,权限管理,缓存等

问:AOP的实现原理

答:代理模式和反射,通过动态代理的方式,为原方法生成代理类,分为JDK动态代理与CGLIB代理两类,如果目标类实现了接口,则采用JDK动态代理,反之则使用CGLIB代理;AOP 代理其实是由 AOP 框架动态生成的一个对象,该对象可作为目标对象使用。AOP 代理包含了目标对象的全部方法,但 AOP 代理中的方法与目标对象的方法存在差异:

问:AOP的一些概念

答:

方面(Aspect):通知和切入点组合形成。

连接点(Joinpoint): 程序执行过程中明确的点,其实对应被代理的对象

通知(Advice): 在连接点上具体做了什么,分为前置,后置,环绕,返回,异常

切点(Pointcut):用来匹配连接点,指定哪些连接点需要执行aop

目标对象(Target Object):目标对象是被一个或者多个切面所通知的对象。

AOP代理(AOP Proxy):生成的AOP代理对象

织入(Wearving):切入点,通知,连接点结合起来的过程

3.Spring事务的传播行为

所谓的事务传播,即多个方法均启用事务的情况下,事务要怎么处理的问题,单独操作?一起回滚?还是其他形式,常用这三种:

PROPAGATION_REQUIRED:

被调用方法加入调用方法的事务,回滚时一起回滚,如果调用方不存在事务则单独执行

PROPAGATION_NESTED:

被调用方法成为调用方法的子事务,调用方回滚时一起回滚,本身回滚不影响调用方,如果调用方不存在事务则单独执行

PROPAGATION_REQUIRES_NEW:

调用方和被调用方全部独立,互不影响,都在各自的事务中运行,不会有关联回归

示范链接:juejin.cn/post/684490…

4.Spring事务的隔离级别

存在的隔离问题:

脏读:读到了其他事务未提交的数据

不可重复读:同一个事务包含对同一数据的多次查询,两次读到值不同,因为其他事务对其进行了修改

幻读:同一个事务包含对同一批数据的多次查询,两次读到数据量不同,因为其他事务对其进行了增删

Spring包含5种隔离级别的设置:

Default : 使用数据库本身使用的隔离级别 ORACLE(读已提交) MySQL(可重复读)

READ_UNCOMITTED:读未提交,可以脏读

READ_COMITTED:读已提交,不能脏读,但能不可重复读

**REPEATABLE_READ:**可重复读,不能不可重复读,但能幻读

**SERLALIZABLE:**最高级别,不能幻读