SpringAop--Java面试题
Spring 的事务隔离级别?
事务隔离的概念:多个事务可以同时访问数据库中的数据,当多个事务在数据库中同时访问(并发)时,数据库的一致性可能会受到破坏,从而导致数据出现问题
为了解决数据库的访问并发问题,Spring有四种事务隔离级别
-
未授权读取、读未提交
一个事务已经开始写数据,另一个事务不允许同时写操作,但允许其他事务读此行数据
-
授权读取、读提交(spring默认的事务隔离级别)
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行
-
可重复读取
读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务
-
序列化
严格的事务隔离级别,要求事务序列化执行,事务只能一个个执行(可以理解为串行执行),不能并发执行
Spring 的事务传播行为?
1>概念
系统中的一些方法交由spring来管理事务,当这些方法出现嵌套调用的时候,事务的表现行为就由事务的传播来决定
2>事务传播的配置
通过@Transactional注解中的propagation属性来指定事务的传播行为
| 事务传播行为类型 | 说明 |
|---|---|
| REQUIRED | 如果当前事务管理器中没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择,是默认的传播行为。 |
| SUPPORTS | 支持当前事务,如果当前事务管理器中没有事务,就以非事务方式执行。 |
| MANDATORY | 使用当前的事务,如果当前事务管理器中没有事务,就抛出异常。 |
| REQUIRES_NEW | 新建事务,如果当前事务管理器中存在事务,把当前事务挂起,然后会新建一个事务。 |
| NOT_SUPPORTED | 以非事务方式执行操作,如果当前事务管理器中存在事务,就把当前事务挂起。 |
| NEVER | 以非事务方式执行,如果当前事务管理器中存在事务,则抛出异常。 |
| NESTED | 如果当前事务管理器中存在事务,则在嵌套事务内执行;如果当前事务管理器中没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
注意:这 7 种传播行为有个前提,他们的事务管理器是同一个的时候,才会有上面描述中的表现行为。Spring 事务传播默认使用 REQUIRED 类型
什么是AoP?AoP与ooP有何区别?
1>Aop的概念
面向切面编程,通过预编译方式和运行期动态代理实现程序功能统一维护的一种技术
- 在Spring中Aop是oop的延续和有益补充,函数式编程的一种泛型
- 在Spring中提供了AOP的丰富支持,允许通过分离应用的业务逻辑与系统级服务和事务管理进行内聚性的并发
2>Aop和OOp的区别
OOP是面向对象编程(两种编程思想,在目标上有本质的差异)
- OOP(面向对象编程):针对业务处理过程的实体及其属性和行为进行抽象封装为对象,以对象作为最基本的逻辑处理单元,并关注对象与对象之间的关系
- AOP(面向切面编程):针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以切面作为最基本的逻辑处理单元,以获得逻辑过程中各部分之间低耦合性的隔离效果
什么是连接点、切点和增强(或通知)?
连接点
往程序中插入代码的点(比如类初始化前后,某个方法调用前后)
切点
定位到特定的连接点,切点相当于查询条件,一个切点可以匹配多个连接点(插入代码位置的查询条件)
增强
织入到目标类连接点上的一段程序代码,在SpringAop中,增强除了用于描述一段程序代码外,还拥有另一个和连接点相关的信息
什么是织入?有哪些织入方式?
1>织入概念
是将增强添加到目标类具体连接点上的过程
2>织入方式
-
编译器织入:要求使用特殊的编译器
-
类装载器织入:要求使用特殊的类装载器
-
动态代理织入:在运行期间为目标类添加增强生成子类的方式
(SpringAop采用动态代理织入方式)
什么是切面?SpringAoP如何定义一个切面?
1>切面
切点+增强组成(包括横切逻辑和连接点的定义)
Spring AOP 负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中
2>SpringAop定义切面
在Spring AOP中定义一个切面(Aspect)通常涉及以下几个步骤:
1. 创建切面类
首先,你需要创建一个类来表示切面。这个类将包含切点(Pointcut)和增强(Advice)。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect // 标识这是一个切面类
@Component // 使Spring能够扫描并管理这个切面
public class MyAspect {
// 这里将定义切点和增强
}
2. 定义切点(Pointcut)
切点定义了增强逻辑应该应用到哪些连接点上。你可以使用@Pointcut注解来声明一个切点。
@Pointcut("execution(* com.yourpackage..*(..))") // 定义切点表达式
public void myPointcut() {
// 切点方法体为空
}
这里的表达式"execution(* com.yourpackage..*(..))"是一个AspectJ表达式,它匹配com.yourpackage包及其子包中所有类的所有方法。
3. 定义增强(Advice)
增强是切面中的核心,它定义了在切点处应该执行的逻辑。Spring AOP支持多种类型的增强,包括:
@Before:在切点方法执行之前执行@After:在切点方法执行之后执行@AfterReturning:在切点方法成功执行之后执行@AfterThrowing:在切点方法抛出异常之后执行@Around:在切点方法执行之前和之后都执行
例如,使用@Before注解定义一个前置增强:
@Before("myPointcut()") // 引用上面定义的切点
public void beforeAdvice(JoinPoint joinPoint) {
// 增强逻辑
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
4. 配置Spring以启用AOP
如果你使用的是Spring Boot,通常不需要额外配置,因为Spring Boot自动配置了AOP。如果你使用的是Spring的XML配置,你需要在配置文件中启用AOP:
<aop:aspectj-autoproxy/>
5. 将切面加入Spring容器
在Spring中,你可以通过@Component注解将切面类加入到Spring容器中,如上面的示例所示。这样,Spring就能够自动识别和管理这个切面。
总结
定义一个切面涉及到创建切面类、定义切点、定义增强逻辑,并将切面加入到Spring容器中。Spring AOP通过代理机制在运行时织入增强,使得你可以在不修改业务逻辑代码的情况下,为应用程序添加横切关注点。
SpringAoP底层实现机制如何?
Spring AOP的底层实现机制主要基于动态代理技术,它通过代理模式在运行时动态地为对象添加额外的功能,这些功能通常被称为“横切关注点”,如日志记录、事务管理等。Spring AOP支持两种动态代理机制:JDK动态代理和CGLIB动态代理。
JDK动态代理
Spring默认使用JDK的动态代理实现AOP。当目标对象实现了一个或多个接口时,Spring会使用JDK的Proxy类和InvocationHandler接口来创建目标对象的代理。在这种机制下,代理对象会实现与目标对象相同的接口,并在代理对象的方法调用中,通过反射机制调用InvocationHandler的invoke方法,从而在方法执行前后添加额外的行为。
CGLIB动态代理
对于没有实现接口的目标对象,Spring AOP会使用CGLIB库来创建代理。CGLIB通过创建目标类的子类来实现代理,这个子类会覆盖目标类的方法,并在这些方法中添加额外的逻辑。CGLIB使用MethodInterceptor来定义代理的行为,捕获方法调用,并在方法调用前后插入自定义的逻辑。
织入机制
Spring AOP的织入机制负责将切面应用到目标对象上,创建新的代理对象。织入可以在不同的阶段发生:
- 编译时织入(Compile-Time Weaving, CTW):在源代码编译成字节码时进行织入,需要AspectJ编译器支持。
- 类加载时织入(Load-Time Weaving, LTW):在类加载到JVM时进行织入,通过自定义类加载器实现。
- 运行时织入(Runtime Weaving):在应用程序运行时进行织入,Spring AOP默认使用这种方式,通过代理机制实现。
Spring AOP通过这些机制,能够在不修改业务逻辑代码的情况下,为应用程序提供灵活的横切关注点管理,增强了代码的模块化和重用性。
有哪些类型的增强(或通知)?
- 前置增强 目标方法执行前实施增强
- 后置增强 在目标方法后实施增强
- 环绕增强 在目标方法执行前后实施增强
- 抛出异常增强 在目标方法抛出异常后实施增强
- 引介增强 在目标类中添加一些新的方法和属性

浙公网安备 33010602011771号