Spring AOP及事务配置三种模式详解
2021-11-17 22:02
645 查看
Spring AOP简述
Spring AOP的设计思想,就是通过动态代理,在运行期对需要使用的业务逻辑方法进行增强。
使用场景如:日志打印、权限、事务控制等。
默认情况下,Spring会根据被代理的对象是否实现接口来选择使用JDK还是CGLIB。当被代理对象没有实现接口时,Spring会选择CGLIB。当实现了接口,Spring会选择JDK官方的代理技术,不过我们也可以通过配置的方式,让Spring强制使用CGLIB。
配置方式有两种:
- 使⽤aop:config标签配置
<aop:config proxy-target-class="true">
- 使⽤aop:aspectj-autoproxy标签配置
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj- autoproxy>
Spring中AOP的实现
2.1 XML模式
- 引入依赖(如果项目里没有的话)
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.1.12.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
- xml配置
主要看下面的aop部分
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans https://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 https://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd ">
xml相关切面配置
<bean id="logUtil" class="com.mmc.ioc.utils.LogUtil"></bean> <!--aop的配置--> <!--aop的配置--> <aop:config> <!--配置切面--> <aop:aspect id="logAdvice" ref="logUtil"> <aop:pointcut id="logAspect" expression="execution(public * com.mmc.ioc.service.impl.TransferServiceImpl.transfer(..))"></aop:pointcut> <!--前置通知--> <aop:before method="printLog" pointcut-ref="logAspect"></aop:before> <!--后置通知,无论业务是否正常执行--> <aop:after method="after" pointcut-ref="logAspect"></aop:after> <!--正常执行--> <aop:after-returning method="afterReturn" pointcut-ref="logAspect"></aop:after-returning> <!--异常执行--> <aop:after-throwing method="afterException" pointcut-ref="logAspect"></aop:after-throwing> <!--环绕通知--> <!--<aop:around method="around" pointcut-ref="logAspect" arg-names="proceedingJoinPoint"></aop:around>--> </aop:aspect> </aop:config>
环绕通知可以实现上面的4种通知,并且可以控制业务方法是否执行。通过如下代码控制:
proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());
public class LogUtil { public void printLog(){ System.out.println("打印日志"); } public void after(){ System.out.println("后日志打印,不管业务是否正常"); } public void afterReturn(){ System.out.println("正常执行完毕打印日志"); } public void afterException(){ System.out.println("异常执行打印日志"); } public void around(ProceedingJoinPoint proceedingJoinPoint){ System.out.println("环绕前置"); try { Object result =proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());System.out.println("环绕正常执行"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("环绕异常执行"); } } }
- 切入点表达式
举例:
public void com.lagou.service.impl.TransferServiceImpl.updateAccountByCardNo(c om.lagou.pojo.Account)
- 访问修饰符可以省略,也就是public可以不用写
void com.mmc.ioc.service.impl.TransferServiceImpl.transfer(String,String,int)
- 返回值可以用*代替,表示返回任意值
* com.mmc.ioc.service.impl.TransferServiceImpl.transfer(String,String,int)
- 包名可以使用..表示当前包及其子包
* com..TransferServiceImpl.transfer(String,String,int)
- 类名和方法名,都可以使用*表示任意类,任意方法
* com..*(String,String,int))
- 参数列表,如果是基本类型可以直接写名称,如int。引用类型必须用全限定名称
- 参数列表可以使用*代替任意参数类型,但必须有参数
* com..*(*)
- 参数列表可以使用..代替任意参数类型,有无参数均可
* com..*(*)
- 全通配方式:
* *..*.*(..)
2.2 XML+注解模式
- XML中开启Spring对注解AOP的支持
<!--开启spring对注解aop的⽀持--> <aop:aspectj-autoproxy/>
- 注解配置
@Component @Aspect public class LogUtil { @Pointcut("execution(* com.mmc.ioc.service.impl.TransferServiceImpl.transfer(..))") public void pointcut(){} @Before("pointcut()") public void printLog(){ System.out.println("打印日志"); } @After("pointcut()") public void after(){ System.out.println("后日志打印,不管业务是否正常"); } @AfterReturning("pointcut()") public void afterReturn(){ System.out.println("正常执行完毕打印日志"); } @AfterThrowing("pointcut()") public void afterException(){ System.out.println("异常执行打印日志"); } // @Around("pointcut()") public void around(ProceedingJoinPoint proceedingJoinPoint){ System.out.println("环绕前置"); try { Object result =proceedingJoinPoint.proceed(proceedingJoinPoint.getArgs());System.out.println("环绕正常执行"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("环绕异常执行"); } } }
2.3 纯注解模式
只需要用注解@EnableAspectJAutoProxy替换掉
<aop:aspectj-autoproxy/>
Spring事务配置
也分为3种模式
3.1 XML模式
- 引入pom依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.12.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.12.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.12.RELEASE</version> </dependency>
- xml配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg name="dataSource" ref="dataSource"></constructor-arg> </bean> <tx:advice id="txAdice" transaction-manager="transactionManager"> <!--定制事务细节--> <tx:attributes> <tx:method name="*" read-only="false" propagation="REQUIRED" isolation="DEFAULT"/> <tx:method name="query*" read-only="true" propagation="SUPPORTS"></tx:method> </tx:attributes> </tx:advice> <!--事务衡器逻辑--> <aop:config> <aop:advisor advice-ref="txAdice" pointcut="execution(* com.mmc.ioc.service.impl.TransferServiceImpl.transfer(..))"></aop:advisor> </aop:config>
3.2 基于XML+注解
- xml配置:
<!--spring声明式事务配置--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg name="dataSource" ref="dataSource"></constructor-arg> </bean> <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
- 在类或方法上面添加@Transactional注解
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
3.3 纯注解
用@EnableTransactionManagement 注解替换掉
<tx:annotation-driven transaction- manager="transactionManager"/>
即可
相关文章推荐
- Spring事务的配置详解:AOP配置数据库操作的事务
- applicationContext-common.xml 之spring tx:advice 和 aop:config 配置事务属性详解
- applicationContext-common.xml 之spring tx:advice 和 aop:config 配置事务属性详解
- Spring事务的配置详解:AOP配置数据库操作的事务
- applicationContext-common.xml 之spring tx:advice 和 aop:config 配置事务属性详解
- Spring AOP中事务配置中七种方式详解
- applicationContext-common.xml 之spring tx:advice 和 aop:config 配置事务属性详解
- VMware网络配置详解:三种网络模式简介及实现
- Spring中annotation-driven配置事务管理器详解
- Spring事务配置详解
- spring 事务配置例子详解
- VMware WorkStation11的三种网络连接方式详解与NAT模式下静态IP配置(Ubuntu12.04版本)
- Spring事务Transaction配置的五种注入方式详解
- Spring 配置 ——事务:aop:config切入
- spring tx:advice 和 aop:config 配置事务
- Atomikos+spring AOP方式实现JTA事务配置的示例
- hibernate事务配置Aop aop:advisor模式
- Spring、Spring事务详解;使用XML配置事务
- Spring事务Transaction配置的五种注入方式详解
- Spring事务Transaction配置的五种注入方式详解