Java -- Spring学习笔记8、AspectJ的AOP配置管理事务
1、AspectJ的AOP配置管理事务
在大型项目中、可以使用AspectJ的AOP配置管理事务。在配置文件中声明类、方法需要的事务。业务和事务配置完全分离。
-
需要四个步骤、如下:
- 添加依赖
- 声明事务管理器对象
- 声明方法需要的事务类型
- 配置aop、指定哪些类需要创建代理
1.1、添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
1.2、声明事务管理器对象
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource"/>
</bean>
1.3、声明方法需要的事务类型
<!--
声明业务方法它的属性、也就是隔离级别、传播行为、超时时间
id:自定义名称
transaction-manager:事务管理器对象的id
-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<!--
tx:attributes:配置事务属性
-->
<tx:attributes>
<!--
tx:method:给具体的方法配置事务属性、可以有多个、分别给不同的方法配置属性
name:方法名称、不要带包名。也可以使用通配符 * 表示任意字符
propagation:传播行为
isolation:隔离级别
rollback-for:指定的异常类名、全限定类名。发生异常先和这里边的进行比对
如果发生的异常类型是这里边的,就回滚,如果不是、而是运行时异常、也会回滚
-->
<tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT"
rollback-for="java.lang.NullPointerException,com.rg.error.NotEnoughException"/>
<!--
这里就给一个buy方法添加了事务、而在项目中方法会有多个,所以就可以使用通配符
使用通配符、接口中的方法命名要有规则
比如:addUser、addSales、addGoods....
removeUser、removeSales、removeGoods....
modifyUser、modifySales、modifyGoods....
selectUser、selectGoods、selectName....
-->
<!--添加-->
<tx:method name="add*" propagation="REQUIRES_NEW"/>
<!--删除-->
<tx:method name="remove*"/>
<!--修改-->
<tx:method name="modify*"/>
<!-- * 就是以上方法以外的、如:query、find、select等等-->
<tx:method name="*" read-only="true" propagation="SUPPORTS"/>
<!--
从上往下、依次匹配
-->
</tx:attributes>
</tx:advice>
1.4、配置aop、指定哪些类需要创建代理
<!--
上边配置中、method的值只是方法名、但是一个项目中不同的包下可能有好多方法名称一样
比如在上边配置中、首先指定的buy方法、那么service包下、dao包下都可能有buy方法
所以、还需要配置切入点表达式、指定哪些类需要事务
-->
<aop:config>
<!--
id:切入点表达式的名称、唯一值
expression:切入点表达式、指定哪些类需要事务、aspectJ会创建代理对象
-->
<aop:pointcut id="serviceCut" expression="execution(* *..service..*.*(..))"/>
<!--
配置器增强、关联advice和pointcut
advice-ref:通知、上边tx:advice中的配置
pointcut-ref:切入点表达式的id
概括来讲、如果切入点表达式里的方法和通知里配置的一样、那么就会有事务的属性了
aspectJ会创建对应的代理对象
-->
<aop:advisor advice-ref="myAdvice" pointcut-ref="serviceCut"/>
</aop:config>
这样、service包下或者子包下左右的buy方法都有了事务属性。业务中如果出现异常、一定回滚。