1.AOP介绍
- AOP(Aspect-Oriented Programming),即面向切面编程,用人话说就是把公共的逻辑抽出来,让开发者可以更专注于业务逻辑开发。
- AOP和IOC一样,AOP也指的是一种思想。AOP思想是OOP(Object-Oriented Programming)的补充。OOP是面向类和对象的,但是AOP则是面向不同切面的。一个切面可以横跨多个类和对象去操作,极大的丰富了开发者的使用方式,提高了开发效率。
2.AOP实现
从Bean的初始化流程中来讲,Spring的AOP会在bean实例的实例化已完成,进行初始化后置处理时创建代理对象
- Spring AOP 是通过代理模式实现的,具体有两种实现方式,一种是基于Java原生的动态代理,一种是基于cglib的动态代理。对应到代码中就是,这里面的Proxy有两种实现,分别是CglibAopProxy和JdkDynamicAopProxy。
- Spring AOP默认使用标准的JDK动态代理进行AOP代理。这使得任何接口可以被代理。但是JDK动态代理有一个缺点,就是它不能代理没有接口的类。
3.声明式事务失效详解
- Spring中比较容易失效的就是通过@Transactional 定义的声明式事务,他在以下几个场景中会导致事务失效,首先,就是Spring的@Transactional是基于Spring的AOP机制实现的,而AOP机制又是基于动态代理实现的。那么如果代理失效了,事务也就会失效。
Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法。
什么情况下会不走代理对象的调用
- 类内部的调用,比如一些私有方法调用,内部类调用,以及同一个类中方法的自调用等不会调用到代理对象,所以代理会失效。
- 类似的还有一种情况,虽然不是对象的自调用,但是他也是因为没有调用到代理对象,那就是调用static方法,因为这类方法是属于这个类的,并不是对象的,所以无法被AOP。
- 还有一种方法,也无法被代理,那就是final方法,由于AOP是通过创建代理对象来实现的,而无法对final方法进行子类化和覆盖,所以无法拦截这些方法。
其他事务失效的情况
异常被捕获
- 被标记类的事务无法捕获到类内异常,不知道要回滚,因为异常被捕获,所以就没办法基于异常进行rollback了,所以事务会失效。
事务用了多线程
- @Transactional 的事务管理使用的是 ThreadLocal 机制来存储事务上下文,而 ThreadLocal 变量是线程隔离的,即每个线程都有自己的事务上下文副本。因此,在多线程环境下,Spring 的声明式事务会失效,即新线程中的操作不会被包含在原有的事务中。
不支持事务
- 这个好理解,如myisam,不支持的肯定就不行