九、Spring事务(aspectJ)
1、实现步骤
-
加入aspectJ依赖
-
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.20</version> </dependency>
-
-
声明事务管理器对象
-
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--...--> </bean>
-
-
声明业务方法需要的事务类型(配置方法的事务属性 [ 隔离级别、传播行为、超时 ])
-
配置AOP(指定哪些类书需要事务管理 [ 创建代理 ])
2、项目结构
与第八章(八、Spring事务(注解方案))一致,唯二变动如下:
pom.xml追加aspectJ依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.20</version>
</dependency>
applicationContext.xml(声明式事务处理第二步开始有变动)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!--声明数据源DataSource,用于连接数据库-->
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--使用属性配置文件中的数据,语法:${key}-->
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!--声明mybatis提供的SqlSessionFactoryBean,用于创建SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="myDataSource"></property>
<property name="configLocation" value="classpath:mybatis.xml"></property><!--在spring配置文件中指定其他配置文件路径需要使用 classpath:-->
</bean>
<!--创建dao对象,使用SqlSession的getMapper(UserDao.class)
MapperScannerConfigurer:在内部调用getMapper()生成每个dao接口的代理对象
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定SqlSessionFactory的id-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!--指定包名(dao所在的包名)
MapperScannerConfigurer会扫描这个包中的所有接口,把每个接口都执行一次 getMapper()方法,得到每个接口的dao对象。创建好的dao对象放入到 spring容器中
-->
<property name="basePackage" value="hom.wang.dao"></property>
</bean>
<bean id="buyService" class="hom.wang.service.impl.BuyServiceImpl">
<property name="goodsDao" ref="goodsDao"></property>
<property name="saleDao" ref="saleDao"></property>
</bean>
<!--声明式事务处理:和源代码完全分离-->
<!--1、声明事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--连接的数据库,指定数据源-->
<property name="dataSource" ref="myDataSource" />
</bean>
<!--2、声明业务方法的事务属性(隔离级别、传播行为、超时)-->
<!--springframework.org/schema/tx/spring-tx-->
<!--属性介绍:
id:自定义名称
transaction-manager:事务管理器对象
-->
<tx:advice id="myAdvice" transaction-manager="transactionManager">
<!--tx:attributes:表示配置事务的属性-->
<tx:attributes>
<!--tx:method:给哪些方法配置事务属性(method可以有多个,分别给不同方法配置事务属性)
name:方法名称(1、完整方法名,不带路径 2、可以使用通配符*)
-->
<tx:method name="buy" propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
<!--...根据不同的前缀通配所有需要开启事务的业务方法
<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
...
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" timeout="-1"/>
其中配置完整方法名优先级最高,其次是带前缀的通配,最次全匹配*
-->
</tx:attributes>
</tx:advice>
<!--配置AOP-->
<aop:config>
<!--配置切入点表达式(哪些包中的类需要使用事务)
id:切入点表达式名称(唯一)
expression:切入点表达式
-->
<aop:pointcut id="servicePointcut" expression="execution(* *..service..*.*(..))"/>
<!--配置增强器:关联 tx:advice 和 aop:pointcut
advice-ref:通知,上面tx:advice的配置
pointcut-ref:切入点表达式,上面的aop:pointcut的配置
两者进行关联(pointcut对应的方法符合advice方法匹配的会创建代理增强相应的事务)
-->
<aop:advisor advice-ref="myAdvice" pointcut-ref="servicePointcut" />
</aop:config>
</beans>
测试代码及结果也和第八章如出一辙~