通过AOP环绕通知如何实现事务控制

网友投稿 884 2022-12-11

通过AOP环绕通知如何实现事务控制

通过AOP环绕通知如何实现事务控制

目录通过AOP环绕通知实现事务控制1、导入相关的依赖2、配置连接池和开启AOP注解2、创建链接工具类3、AOP环绕事务类spring AOP 环绕通知的思路1、设计一个接口2、编写这个接口的实现3、编写前置通知的逻辑代码4、编写XML配置文件

通过AOP环绕通知实现事务控制

1、导入相关的依赖

org.springframework

spring-context

5.0.2.RELEASE

c3p0

c3p0

0.9.1.2

org.aspectj

aspectjweaver

1.8.7

2、配置连接池和开启AOP注解

以下采用的是xml配置方式,当然也可以使用纯注解配置

2、创建链接工具类

package com.gzl.utils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import javax.sql.DataSource;

import java.sql.Connection;

/**

* 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定

*/

@Component("connectionUtils")

public class ConnectionUtils {

private ThreadLocal tl = new ThreadLocal();

@Autowired

private DataSource dataSource;

/**

* 获取当前线程上的连接

* @return

*/

public Connection getThreadConnection() {

try{

//1.先从ThreadLocal上获取

Connection conn = tl.get();

//2.判断当前线程上是否有连接

if (conn == null) {

//3.从数据源中获取一个连接,并且存入ThreadLocal中

conn = dataSource.getConnection();

tl.set(conn);

}

//4.返回当前线程上的连接

return conn;

}catch (Exception e){

throw new RuntimeException(e);

}

}

/**

* 把连接和线程解绑

*/

public void removeConnection(){

tl.remove();

}

}

3、AOP环绕事务类

package com.gzl.utils;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.*;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

/**

* 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接

*/

@Component("txManager")

@Aspect

public class TransactionManager {

@Autowired

private ConnectionUtils connectionUtils;

/**

* 需要进行事务控制的类或者方法,EL表达式配置

*/

@Pointcut("execution(* com.gzl.service.impl.*.*(..))")

private void pt1(){}

/**

* 开启事务

*/

public void beginTransaction(){

try {

connectionUtils.getThreadConnection().setAutoCommit(false);

}catch (Exception e){

e.printStackTrace();

}

}

/**

* 提交事务

*/

public void commit(){

try {

connectionUtils.getThreadConnection().commit();

}catch (Exception e){

e.printStackTrace();

}

}

/**

* 回滚事务

*/

public void rollback(){

try {

connectionUtils.getThreadConnection().rollback();

}catch (Exception e){

e.printStackTrace();

}

}

/**

* 释放连接

*/

public void release(){

try {

connectionUtils.getThreadConnection().close();//还回连接池中

connectionUtils.removeConnection();

}catch (Exception e){

e.printStackTrace();

}

}

@Around("pt1()")

public Object aroundAdvice(ProceedingJoinPoint pjp){

Object rtValue = null;

try {

//1.获取参数

Object[] args = pjp.getArgs();

//2.开启事务

this.beginTransaction();

//3.执行方法

rtValue = pjp.proceed(args);

//4.提交事务

this.commit();

//返回结果

return rtValue;

}catch (Throwable e){

//5.回滚事务

this.rollback();

throw new RuntimeException(e);

}finally {

//6.释放资源

this.release();

}

}

}

spring AOP 环绕通知的思路

环绕通知Around Advice就是在指定的程序前后均执行相关的服务,设计思路如下:

1、设计一个接口

package com.spring.service;

public interface IComponent {

public void bussiness1();

public void bussiness2();

public void bussiness3();

}

2、编写这个接口的实现

package com.spring.service;

public class Component implements IComponent{

@Override

public void bussiness1() {

// TODO Auto-generated method stub

System.out.println("这是业务1");

}

@Override

public void bussiness2() {

// TODO Auto-generated method stub

System.out.println("这是业务2");

}

@Override

public void bussiness3() {

// TODO Auto-generated method stub

System.out.println("这是业务3");

}

}

3、编写前置通知的逻辑代码

该代码必须实现org.aopalliance.intercept.Method Interceptor接口,需要的服务都写在这里。

4、编写XML配置文件

通过代理来实现AOP的环绕通知,看一下org.aopalliance.intercept.MethodInterceptor接口的源代码。该接口不是Spring内部的接口,而是AOP Alliance标准所指定的,不过Spring对这个接口有一个具体的实现过程,同时该接口相融所有遵守AOP Alliance标准的所有AOP框架。

环绕通知相当于前置通知和后置通知的结合,不同的是在MethodInterceptor的invoke()方法中,可以自由地使用MethodInvocation提供的proceed()方法来执行目标对象的方法,同时proceed()方法将会返回目标方法执行后的返回结果,在invoke方法结束前还可以修改该结果,下面还是以上面的那个例子来示范一下环绕通知的应用。

编写一个环绕通知的类,该类实现MethodInterceptor接口。这里调用了MethodInvocation的proceed()方法,也就是说,调用了目标对象Component中的business1等方法,在这个方法的前后分别增加了验证和通知执行,接着修改一下配置文件,去掉前置通知和后置通知的配置,只需要将这个环绕通知添加进去就可以了,具体代码如下:

这里只需要配置一个环绕通知的Bean,并且将这个Bean配置到interceptorNames中就完成了所有的工作,测试代码与前面的相同,可以看到结果也与前面的相同。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringAOP四种通知类型+环绕通知说明
下一篇:Mybaits处理mysql主键自动增长出现的不连续问题解决
相关文章

 发表评论

暂时没有评论,来抢沙发吧~