Java面试宝典 (二) | Spring全家桶源码篇

Scroll Down

前言

这里讲解的都是一些框架流程、工具以及源码分析篇的面试题,具体如下:

  1. spring boot 篇
  2. spring 篇
  3. spring 事务
    ...

一、spring boot

1、对spring boot有什么理解

1、一站式单机开发
2、约定大于配置
3、从繁琐的xml中解脱
4、内置tomcat容器
5、打包成jar部署更简单

2、spring boot分析启动流程

1、创建SpringApplication对象初始化SpringBoot容器
2、获得应用启动类型。(原理:判断classPath是否有加载servlet类,返回启动方式)
3、setlnitializers读取sb包下spring.factories获取ApplicationContentlnitializer装配集合
4、setListeners读取spring.factories获取ApplicationListener装配集合
5、MainApplication 获取当前运行主函数
6、调用run启动方式
7、StopWatch stopWatch = new StopWatch()记录项目启动时间
8、getRunListeners类型存入集合
9、listeners.Starting 循环监听starting 方法
10、prepareEnvironment 读取配置文件SpringBoot 容器
11、打印Banner日志
12、创建SpringBoot上下文 对象
13、refreshContext 刷新我们山下文
14、创建tomcat容器
15、创建SpringMvc
16、afterRefresh定义
17、listeners.started 广播和回调机制通知监听器启动成功
18、listeners.runing 广播和回调机制通知监听器以及运行

3、WebApplicationType 三种状态

NONE	 不会嵌入web服务器,通过外部tomcat服务器启动
SERVLET  servlet服务器运行
REAVTIVE 响应式启动

二、spring

1、spring启动流程(简述)

1、执行web.xml中的ContextLoaderListener监听器
2、初始化 contextInitialized方法
3、调用父类(ContextLoader)的initWebApplicationContext方法
4、创建WebApplicationContext容器
5、加载context-param中配置的spring配置文件
6、初始化java bean

停止时候会执行ContextLoaderListener的contextDestroyed方法销毁context容器

三、spring 事务

1、什么是事务

事务指逻辑上一组操作,要么全部成功,要么全部回滚失败

2、事物特性(ACID)

  • 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么都发生,要么都不发生
  • 一致性:执行事务前后,数据保持一致
  • 隔离型:多用户并发访问数据库时候,每个用户事务不被其他事务干扰,多个并发之间数据相互隔离(涉及到隔离级别)
  • 持久性:一个事务被提交之后。它对数据库中数据的改变是永久性的,即使数据库发生故障也不应该对其有任何影响

3、事务管理高层抽象接口

  • PlatformTransactionManager 事务管理器
  • TransactionDefinition 事务定义信息(隔离级别、传播、超时、只读、回滚)
  • TransactionStatus 事务具体运行状态

3.1、PlatformTransactionManager 事务管理器

spring并不直接提供事务管理,而是提供了多种事务管理器,职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

public interface PlatformTransactionManager { 
    // Return a currently active transaction or create a new one, according to the specified propagation behavior
    //(根据指定的传播行为,返回当前活动的事务或创建一个新事务。)
    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; 
    // Commit the given transaction, with regard to its status
    //(使用事务目前的状态提交事务)
    Void commit(TransactionStatus status) throws TransactionException;  
    // Perform a rollback of the given transaction
    //(对执行的事务进行回滚)
    Void rollback(TransactionStatus status) throws TransactionException;  
} 

3.2、TransactionDefinition 事务定义信息(隔离级别、传播、超时、只读、回滚)

定义

PlatformTransactionManager类中getTransaction方法的事务属性。
事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面

public interface TransactionDefinition {
    // 返回事务的传播行为
    int getPropagationBehavior(); 
    // 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据
    int getIsolationLevel(); 
    // 返回事务必须在多少秒内完成
    //返回事务的名字
    String getName();
    int getTimeout();  
    // 返回是否优化为只读事务。
    boolean isReadOnly();
} 

事务隔离级别(定义了一个事务可能受其他并发事务影响的程度)

多个用户对统一数据进行操作,并发事务带来的问题

  • 脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的
  • 丢失修改:
  • 不可重复读:同一事务中,多次读取同一数据返回结果有所不同
  • 幻读:A事务读取了几行记录后,B事务插入一些记录,幻读就发生了。后来查询中,A事务就会发现有些数据没有读取到的几行记录。查询结果不一致
隔离级别含义
DEFAULT数据库默认隔离级别
READ_UNCOMMITED允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
READ_COMMITED允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
REPEATABLE_READ对相同字段多次读取是一致的,除非数据被事务本身改变。可以阻止脏读和不可重复读,但幻读仍有可能发生
SERIALIZABLE(串行)最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,它是典型通过完全锁在事务中涉及数据表来完成的

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

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

传播行为是否支持当前事务说明
PROPAGATION_REQUIREDY如果存在 就新建一个
PROPAGATION_SUPPORTSY如果不存在,就不使用事务
PROPAGATION_MANDATORYY如果不存在,抛异常
PROPAGATION_REQUIRES_NEWN挂起当前事务,创建新事务
PROPAGATION_NOT_SUPPORTSN非事务方式运行,有事务就挂起当前
PROPAGATION_NEVERN非事务方式运行,有事务存在就抛异常
PROPAGATION_NESTEDN存在当前事务就嵌套事务执行

事务超时属性(一个事务允许执行的最长时间)

所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。

事务只读属性(对事物资源是否执行只读操作)

事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、 JMS 资源,以及自定义的事务性资源等等

回滚规则(定义事务回滚规则)

这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚

3.3、TransactionStatus 事务运行状态

TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息.

TransactionStatus接口接口内容如下:

public interface TransactionStatus{
    boolean isNewTransaction(); // 是否是新的事物
    boolean hasSavepoint(); // 是否有恢复点
    void setRollbackOnly();  // 设置为只回滚
    boolean isRollbackOnly(); // 是否为只回滚
    boolean isCompleted; // 是否已完成
}