面向切面(AOP)——第二个核心思想
面向切面概述
定义
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP 的作用及优势
作用:在程序运行期间,不修改源码对已有方法进行增强。优势:减少重复代码、提高开发效率、维护方便
AOP 的实现方式
使用动态代理技术
AOP:面向切面的编程。是对面向对象思维的一种补充。
场景:
有一些共同的功能:日志,事物。比如有多个模块下的功能类似,想给每个add方法都添加日志,或者每个添加方法之前开启事物,每个添加方法之后关闭事物。
实现面向切面
1.修改配置文件
2.导入AOP的Maven坐标
注解方式
1.创建切面类并在切面类中加入配置(aop ----method----通知类型:表达式 )
创建一个切面类,这个类就是一个切面,既然是一个类,就得spring管理。
2.测试
XML方式
1.切面类
只留下方法,把注解全部去掉
2.beans.xml
通知类型
前置通知
@Before作用:把当前方法看成是前置通知。属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用。
后置通知
@AfterReturning作用:把当前方法看成是后置通知。属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用
环绕通知
@Around作用:把当前方法看成是环绕通知。属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用。
方法之前和之后都执行一下
抛出异常后通知
@AfterThrowing作用:把当前方法看成是异常通知。属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用
正常情况是没有输出
模拟一个异常,就出抛出异常通知。
但是如果try.....catch.....就不会抛出异常通知。因为spring以为异常已经处理了。
最终通知
@After作用:把当前方法看成是最终通知。属性:lue:用于指定切入点表达式,还可以指定切入点表达式的引用
不管有没有异常,都会执行,类似finally
PS:通知是通过Java的动态代理来实现的。动态代理就像UserDaoImpl的秘书。在他真正处理之前之后秘书处理一些事情。
切入点表达式
声明式事务管理
第一步:导入事务管理坐标
第二步:在核心配置文件中配置事务的命名空间
第三步:配置事务管理器的控制反转对象
XML方式:
注解方式:
在需要控制事务的业务层方法上标注@Transactional
注意:如果在声明式事务管理中,发生的异常是运行时异常,那么事务自动回滚,如果是非运行时异常,那么事务不回滚,需要手动设置
事务传播级别
在Spring框架中,事务传播机制用于定义在多个事务性方法相互调用时,事务如何传播和交互的规则。Spring框架提供了七种不同的事务传播行为:
REQUIRED(需要有):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是最常用的传播行为。
SUPPORTS(可以有):如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
MANDATORY(强制有):如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
REQUIRES_NEW:创建一个新的事务,并挂起当前事务(如果存在)。新创建的事务与当前事务完全独立。
NOT_SUPPORTED:以非事务方式执行,并且挂起当前事务(如果存在)。
NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED:如果当前存在事务,则在嵌套事务中执行。嵌套事务是独立于当前事务的子事务,它可以独立地进行提交或回滚。如果当前没有事务,则创建一个新的事务。
这些事务传播行为可以通过@Transactional注解的propagation属性进行设置。例如:
需要注意的是,事务传播行为仅在方法之间的调用时才会生效,对于同一个方法内部的事务性操作,传播行为不会起作用。
如果将事务比作房子,以伴侣为例子理解(以下图片来自网络):
嵌套事务(NESTED)和加入事务(REQUIRED )的区别
- 整个事务如果全部执行成功,二者的结果是一样的。
- 如果事务执行到一半失败了,那么加入事务整个事务会全部回滚;而嵌套事务会局部回滚,不会影响上一个方法中执行的结果。