手写事务 AOP 切面类

思路
1.自定义注解
2.AOP类 拦截获取目标对象的方法及其是否存在注解

一。实现一个切面

1.自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtTransaction {
}

2.AOP切面类

@Aspect
@Component
public class AOPTransaction {
    @Autowired
    TransactionUtils transactionUtils;


    @Pointcut("execution(* com.aop.web.service.*.*(..))")
    private void pointCut(){

    };

    @Around("com.aop.DIY.AOPTransaction.pointCut()")                 --上面有预先定义一个切点
    @Around("execution(* javax.sql.DataSource.getConnection(..))")   --直接指到要切面的具体方法
    @Around("execution(* com.aop.web.service.*.*(..))")              --直接指到包下       
    @Around("@annotation(com.lhc.annotation.GlobalTransaction )")    --直接指到注解
    public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
        //1.获取到目标对象的方法
        //2.获取该方法上是否加上注解
        //3.如果存在事务,开启事务
        //4.调用目标对象方法
        //5.判断该方法是否存在注解
        //6.如果存在注解提交事务
        System.out.println("AOP类进入拦截");
        Object proceed = null;
        TransactionStatus transactionStatus = null;

        //1.百度SpringAOP获取目标对象的方法
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method targetMethod = methodSignature.getMethod();

        //2.判断方法是否存在注解
        ExtTransaction extTransaction = targetMethod.getDeclaredAnnotation(ExtTransaction.class);
        if(extTransaction != null){
            //3.如果存在注解,开启事务
            transactionStatus = transactionUtils.begin();
        }
        //4.调用目标对象方法
        proceed = pjp.proceed();

        //5.判断该方法是否存在注解
        if(extTransaction != null){
            //6.如果存在注解,提交事务
            transactionUtils.commit(transactionStatus);
        }
        return proceed;
    }
}

切面类另外一种写法:写注解的位置,前缀是@annotation
上面写要拦截的类的位置,前缀是execution
@Aspect
@Component
public class GlobalTransactionAspect {
    @Around("@annotation(com.lhc.annotation.GlobalTransaction )")
    public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        Method method = methodSignature.getMethod();                                   //拿到切的方法
        GlobalTransaction annotation = method.getAnnotation(GlobalTransaction.class);  //方法上的注解
        annotation.isStart()                                                           //注解上的值                                    
    }

3.serviceImpl(即目标对象)方法上加注解

@Override
@ExtTransaction
public int insertRoleMenu() {
    wholeDepartmentMapper.insertRoleMenu();
    int j = 1/0;
    return j;
}

二。设置切面类的优先级(假如有两个切面类)

实现 org.springframework.core.Ordered 接口,重写getOrder方法(返回的整形越大越优先)

@Aspect
@Component
public class GlobalTransactionAspect implements Ordered {
    @Around("@annotation(com.lhc.txtransaction.annotation.GlobalTransaction )")
    public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
       pjp.proceed();
    }

    @Override
    public int getOrder() {
        return 100000;
    }
}

三。切面类拿到目标对象的方法,方法上的注解,注解值

public class GlobalTransactionAspect implements Ordered {
    @Around("@annotation(com.lhc.txtransaction.annotation.GlobalTransaction )")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("进入GlobalTransactionAspect切面类");

        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        Method method = methodSignature.getMethod();
        GlobalTransaction annotation = method.getAnnotation(GlobalTransaction.class);
        annotation.isStart()   //GlobalTransaction这个注解的值
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飘然生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值