1.Spring MVC

  • 谈谈自己对 Spring MVC 的了解

    MVC 是模型、视图、控制器的简写,核心思想是通过将业务逻辑、数据、显示分离来组织代码,MVC 是一种设计模式,而 Spring MVC 是很优秀的 MVC 框架,Spring MVC 可以更简洁的进行 Web 层的开发

  • Spring MVC 的核心组件有哪些?
    • DispatcherServlet:核心的中央处理器,负责接收请求、分发并给予客户端相应
    • HandlerMapping:处理器映射器,根据 uri 去匹配查找到能处理的 Handler,并会将请求设计到的拦截器和 Handler 一起封装
    • HandlerAdapter:处理器适配器,根据 HandlerMapping 找到 Handler,适配器执行对应的 Handler
    • Handler:请求处理器,处理实际请求的处理器
    • ViewResolver:视图解析器,根据 Handler 返回的逻辑视图,解析并渲染真正的视图,并传递给 DispatcherServlet 相应客户端
  • Spring MVC 工作原理了解吗?
    • 客户端发送请求,DispatcherServlet 拦截请求
    • DispatcherServlet 根据请求信息调用 HandlerMapping,HandlerMapping 根据 uri 去匹配查找匹配的的 Hander(Controller 控制器),并会吧请求设计到的拦截器和 Handler 一起封装返回给 DispatcherServlet
    • DispatcherServlet 再调用 HandlerAdapter 适配器执行 Handler
    • Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给 DispatcherServlet,这个对象包含了数据模型以及相应的视图信息
    • DispatcherServlet 吧这个对象交给 ViewResolver ,会根据逻辑 View 查找实际的 View
    • DsipatcherServlet 再吧返回的 Model 传给 View 视图
    • 最后吧 View 返回给客户端浏览器
  • 统一异常处理怎么做?

    通过在类上使用 @RestControllderAdvice,成员方法上使用 @ExceptionHandler。在这种异常处理的方式下,会给所有或者是指定的 Controller 织入异常处理的逻辑(AOP),当 Controller 中的方法抛出异常的时候,就由被 @ExceptionHandler 注解修饰的方法进行处理【ExceptionHandlerMethodResolver 中 getMappedMethod 方法决定了异常具体被哪个 @ExceptionHandler 注解修饰的方法处理异常。getMappedMethod() 会首先找到可以匹配处理异常的所有方法信息,然后进行从小到大范围的排序,最后去最小的一个匹配方法】

  • Spring 框架中用到了哪些设计模式?
    • 工厂设计模式:通过 BeanFactory、ApplicationContext 创建 bean 对象
    • 代理设计模式:Spring AOP 功能的实现
    • 单例设计模式:Spring 中 bean 默认都是单例的
    • 模板方法模式:Spring 中以 Template 结尾的对数据库操作的类,都用到了模板模式【jdbcTemplate】
    • 包装器设计模式:项目一般需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库,这种模式让我们可以根据客户的需求能够动态的切换不同的数据源
    • 适配器模式:Spring AOP 的增强就是使用到了适配器模式,Spring MVC 中也是用到了适配器模式来适配 Controller

2.Spring 事务

  • Spring 管理事务的方式有几种?
    • 编程式事务:在代码中硬编码:通过 TransactionTemplate 或者 TransactionManager 手动管理事务【很少用到】
    • 声明式事务:在 XML 配置文件或者直接基于注解的方式:实际是通过 AOP 实现的
  • Spring 事务中有哪几种事务传播行为?

    事务传播行为是为了解决业务层方法之间互相调用的事务问题,当事务方法被另一个事务方法调用的时候,必须指定事务应该如何传播【比如:方法可能继续在现有的事务中运行,也可能开启一个新的事务】

    • TransactionDefinition.propagation_required:使用最多的一个事务传播行为,@Transactional 注解默认使用的就是该事务传播行为。表示如果当前存在事务,则加入,不存在,则创建一个新的事务
    • TransactionDefinition.propagation_requires_new:创建一个新的事务,如果当前存在蛇舞,则挂起当前事务,且开启的事务相互独立,互不干扰
    • TransactionDefinition.propagation_nested:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行。如果当前没有事务,则取值等价于 TransactionDefinition.propagation_required
    • TransactionDefinition.propagation_mandatory:如果当前存在事务,则加入该事务,如果没有,则抛出异常【很少使用】

    若是错误的配置以下 3 种,事务不会发生回滚

    • TransactionDefinition.propagation_supports:如果当前存在事务,则加入事务,如果当前没有事务,则以非事务的方式继续运行
    • TransactionDefinition.propagation_not_supported:以非事务方式运行,如果当前存在事务,则吧当前事务挂起
    • TransactionDefinition.propagation_never:以非事务方式运行,如果当前存在事务,则抛出异常

    【常见的配置错误:1.在同一个类中调用。2.@transactional 修饰的不是 public。3.不同的数据源。4.回滚异常配置不正确。5.数据库引擎不支持事务】

  • Spring 事务种的隔离级别有哪几种?
    • TransactionDefinition.isolation_default:使用后端数据库默认的隔离级别,MySQL 默认采用的 repeatable_read(可重复读) 隔离级别。Oracle 默认采用的 read_committed(读提交) 隔离级别
    • TransactionDefinition.isolation_read_uncommitted:最低的隔离级别,很少使用,因为它允许读取尚未提交的数据变更,可能导致脏读、幻读或不可重复读
    • TransactionDefinition.isolation_read_committed:允许读取并发事务已经提交的事务,可以组织脏读,但幻读和不可重复读还会有可能发生
    • TransactionDefinition.isolation_repeatable_read:对同一字段的多次读取结果是一致的,除非数据是被本身事务自己所修改,可以组织脏读和不可重复读,但幻读还会有可能发生
    • TransactionDefinition.isolation_serializable:最高的隔离级别,遵从 ACID 的隔离级别,所有的事务依次逐个执行,这样事务之间就不可能产生干扰,该级别可以防止脏读、不可重复读以及幻读,但会严重影响程序的性能,一般不会使用到该级别
  • @Transactional(rollbackFor = Exception.class) 注解了解吗?

    当 @Transaction 注解作用到类上,该类的所有 public 方法都将具有该类型的事务属性,也可以在方法上使用。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库的相应数据也会回滚。如果不配置 rollbackFor 属性,那么事务只会在遇到运行时异常才会回滚,加上则事务在遇到非运行时异常也回滚

3.Spring Data JPA

  • 如何使用 JPA 在数据库中非持久化一个字段?
    • 使用 static 修饰该字段
    • 使用 final 修饰该字段
    • 使用 transient 修饰该字段
    • 使用 @Transient 注解
  • JPA 的审计功能是什么?有什么用?

    审计功能主要是帮助纪律数据库操作的具体行为,比如某条记录是谁创建的、什么时间创建的、最后修改人是谁、最后修改时间是什么

    • @CreateData:表示该字段为创建时间字段,在 insert 的时候,会设置值
    • @GreateBY:表示该字段为创建人,在 insert 的时候,会设置值
    • @LastModifiedData、@LoastModifiedBy 同理
  • 实体之间的关联关系注解有哪些?
    • @OneToOne:一对一
    • @ManyToMany:多对多
    • @OneToMany:一对多
    • @ManyToOne:多对一

4.Spring Security

  • 有哪些控制请求访问权限的方法?
    • permitAll():无条件允许任何形式访问,不管是登录还是没登录
    • anonymous():允许匿名访问,也就是没有登录才可以访问
    • denyAll():无条件拒绝任何形式的访问
    • authenticated():只允许已认证的用户访问
    • fullyAuthenticated():只允许已经登录或者通过 remember-me 登录的用户访问
    • hasRole(String):只允许指定的角色访问
    • hasAnyRole(String):指定一个或者多个角色,满足一个就可以访问
    • hasAuthority(String):只允许具有指定权限的用户可以访问
    • hasAnyAuthority(String):指定一个或多个权限,满足一个就可以访问
    • hasIpAddress(String):只允许指定 ip 的用户访问
  • 如何对密码进行加密?

    Spring Security 提供了多种加密算法的实现,非常方便。所有加密算法实现类的父类是 PasswordEncoder,如果需要自己实现加密算法,则需要集成 PasswordEncoder

  • 如何更好的更换系统使用的加密算法?

    通过 DelegatingPasswordEncoder,它兼容多种不同的密码加密方案,以适应不同的业务需求,本质是一个代理类,Spring Security 5.0 后,默认就是基于它来进行密码加密的

results matching ""

    No results matching ""