《我要进大厂》- Spring框架 夺命连环22问,你能坚持到第几问?(Spring高频问题)(三)

简介: 《我要进大厂》- Spring框架 夺命连环22问,你能坚持到第几问?(Spring高频问题)

6.2 SpringMVC 工作原理了解吗?


Spring MVC 原理如下图所示:


SpringMVC 工作原理的图解我没有自己画,直接图省事在网上找了一个非常清晰直观的,原出处不明。


de6d2b213f112297298f3e223bf08f28.png


流程说明(重要):


客户端(浏览器)发送请求,直接请求到 DispatcherServlet (前端控制器)。

DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。

解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。

HandlerAdapter 会根据 Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。

ViewResolver 会根据逻辑 View 查找实际的 View。

DispaterServlet 把返回的 Model 传给 View(视图渲染)。

把 View 返回给请求者(浏览器)

七、Spring 框架中用到了哪些设计模式?

关于下面一些设计模式的详细介绍,可以看笔主前段时间的原创文章《面试官:“谈谈 Spring 中都用到了那些设计模式?”。》 。


工厂设计模式 : Spring 使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。


解释:BeanFactory是负责生产和管理bean的一个工厂。多种实现:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。


代理设计模式 : Spring AOP 功能的实现。


单例设计模式: Spring 中的 Bean 默认都是单例的。


模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。


包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。


观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。


适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。



八、Spring 事务


Spring/SpringBoot 模块下专门有一篇是讲 Spring 事务的,总结的非常详细,通俗易懂。


8.1 Spring 管理事务的方式有几种?


编程式事务 : 在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。

声明式事务 : 在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)


8.2 Spring 事务中哪几种事务传播行为?


事务传播行为是为了解决业务层方法之间互相调用的事务问题。


当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。


正确的事务传播行为可能的值如下:


1.TransactionDefinition.PROPAGATION_REQUIRED


使用的最多的一个事务传播行为,我们平时经常使用的@Transactional注解默认使用就是这个事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。


2.TransactionDefinition.PROPAGATION_REQUIRES_NEW


创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。


3.TransactionDefinition.PROPAGATION_NESTED


如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。


4.TransactionDefinition.PROPAGATION_MANDATORY


如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)


这个使用的很少。


若是错误的配置以下 3 种事务传播行为,事务将不会发生回滚:


TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。


8.3 Spring 事务中的隔离级别有哪几种?


和事务传播行为这块一样,为了方便使用,Spring 也相应地定义了一个枚举类:Isolation


public enum Isolation {
    DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
    READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
    READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
    REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
    SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
    private final int value;
    Isolation(int value) {
        this.value = value;
    }
    public int value() {
        return this.value;
    }
}

下面我依次对每一种事务隔离级别进行介绍:


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 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。


8.4 @Transactional(rollbackFor = Exception.class)注解了解吗?


Exception 分为运行时异常 RuntimeException 和非运行时异常。事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性。


当 @Transactional 注解作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。如果类或者方法加了这个注解,那么这个类里面的方法抛出异常,就会回滚,数据库里面的数据也会回滚。


在 @Transactional 注解中如果不配置rollbackFor属性,那么事务只会在遇到RuntimeException的时候才会回滚,加上 rollbackFor=Exception.class,可以让事务在遇到非运行时异常时也回滚。


九、JPA


9.1 如何使用 JPA 在数据库中非持久化一个字段?


关于什么是JPA,请参考:


基于ORM思想实现的框架都称为JPA框架

JPA 是一个基于O/R映射的标准规范,只定义标准规则(如注解、接口),不提供实现。

JPA 的主要实现有Hibernate、EclipseLink 和OpenJPA 等

假如我们有下面一个类:


@Entity(name="USER")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;
    @Column(name="USER_NAME")
    private String userName;
    @Column(name="PASSWORD")
    private String password;
    private String secrect;
}

如果我们想让secrect 这个字段不被持久化,也就是不被数据库存储怎么办?我们可以采用下面几种方法:

static String transient1; // not persistent because of static
final String transient2 = "Satish"; // not persistent because of final
transient String transient3; // not persistent because of transient
@Transient
String transient4; // not persistent because of @Transient

一般使用后面两种方式比较多,我个人使用注解的方式比较多。

总结

OK,今天关于 Spring框架 的高频面试题分享就到这里,希望本篇文章能够帮助到大家,同时也希望大家看后能学有所获!!!

好了,我们下期见~

相关文章
|
14小时前
|
Java 开发者 Spring
自动装配在Spring框架中的原理与实现方式
自动装配在Spring框架中的原理与实现方式
|
1天前
|
监控 负载均衡 Java
Spring Boot与微服务治理框架的集成
Spring Boot与微服务治理框架的集成
|
1天前
|
存储 Java 数据中心
Spring Boot与微服务治理框架的集成成功案例
Spring Boot与微服务治理框架的集成成功案例
|
3天前
|
监控 负载均衡 Java
Spring Boot与微服务治理框架的集成
Spring Boot与微服务治理框架的集成
|
3天前
|
开发框架 Java 开发者
Spring框架的最新功能与应用案例解析
Spring框架的最新功能与应用案例解析
|
1天前
|
负载均衡 监控 Java
Spring Boot与微服务治理框架的集成方法
Spring Boot与微服务治理框架的集成方法
|
2天前
|
负载均衡 监控 Java
Spring Boot与微服务治理框架的集成方法
Spring Boot与微服务治理框架的集成方法
|
2天前
|
存储 Java 数据中心
Spring Boot与微服务治理框架的集成成功案例
Spring Boot与微服务治理框架的集成成功案例
|
2天前
|
Java 开发者 Spring
自动装配在Spring框架中的原理与实现方式
自动装配在Spring框架中的原理与实现方式
|
2天前
|
XML 监控 Java
Spring框架的核心原理与应用实践
Spring框架的核心原理与应用实践