spring常用面试题及解读(1)

115 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1.Spring的概述:

Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。Spring 主要有两大核心特性:
(1)IOC(控制反转)或DI(依赖注入):即将创建及管理对象的权利交给Spring容器。Spring是一个轻型容器(light-weight Container),其核心是Bean工厂(Bean Factory),用以构造我们所需要的M(Model)。能够让相互协作的软件组件保持松散耦合。降低了业务对象替换的复杂性,提高了组件之间的解耦。
(2)AOP(面向切面编程):通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。即系统级的服务从代码中解耦出来。例如:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来。允许你把遍布应用各处的功能分离出来形成可重用组件。

2. Spring事务的传播级别

Spring中事务的定义:
事务传播行为(propagation behavior):当一个事务方法被另一个事务方法调用时,这个被调用的事务方法应该如何运行。
一、Propagation :
Spring 定义了7种事务的传播级别:
(1)PROPAGATION_REQUIRED 如果当前存在事务,方法将会在该事务中运行,否则,会启动一个新的事务(Spring默认的传播行为)。
(2)PROPAGATION_REQUIRED_NEW 当前的方法必须开启一个新的事务,并在自己的事务内运行。如果有事务在运行,在方法执行期间将这个事务挂起。
(3)PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
(4)PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
(5)PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
(6)PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
其中主要使用的有两种:
(7)PROPAGATION_NESTED 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独的提交或回滚。如果当前事务不存在,那么其行为和 PROPAGATION_REQUIRED一样。

3.对AOP的理解

面向切面的编程AOP,是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
AOP的核心是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。
比如,一个日志模块可以被称作日志的AOP切面。
根据需求的不同,一个应用程序可以有若干切面。
在SpringAOP中,切面通过带有@Aspect注解的类实现。关注点是应用中的一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。切点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。引入运行我们在已存在的类中添加新的方法和属性。

4.Spring如何处理线程并发问题?

Spring使用ThreadLocal解决线程安全问题。
我们知道在一般情况下,只有有状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
(1)在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
(2)而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
(3)概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。