开发者社区> 问答> 正文

spring 的aop顺序问题

@Aspect
public class FourAdviceTest {
     
    @Around("execution(* com.dong.model.*.*(..))")
    public Object processTx(ProceedingJoinPoint jp) throws java.lang.Throwable{
        System.out.println("Around 增强:执行目标方法之前, 模拟开始事务");
         
        Object[] args = jp.getArgs();   //拿到目标方法的参数
        if(args != null && args.length > 0 && args[0].getClass() == String.class){
            args[0] = "被改变的方法";
        }
         
        Object rvt = jp.proceed(args);  //执行目标方法,拿到返回值
        System.out.println("Around 增强: 执行目标方法之后,模拟事务结束");
         
        return rvt + "新增的内容";
    }
     
    @Before("execution(* com.dong.model.*.*(..))")
    public void authority(JoinPoint jp){
        System.out.println("Before 增强: 模拟执行权限检查");
        System.out.println("Before 增强: 被织入增强处理的目标方法为:  " + jp.getSignature().getName());
         
         
        System.out.println("Before 增强: 目标方法的参数是: " + Arrays.toString(jp.getArgs()));
        System.out.println("Before 增强: 被织入增强处理的目标对象时:  " + jp.getTarget());
         
    }
     
     
    @After("execution(* com.dong.model.*.*(..))")
    public void release(JoinPoint jp){
        System.out.println("After 增强处理:模拟方法结束后的释放资源");
        System.out.println("After 增强处理:被织入处理方法的目标方法为:"  + jp.getSignature().getName());
        System.out.println("After 增强处理:目标方法的参数为:" + jp.getArgs());
        System.out.println("After 增强处理:被织入增强处理的目标对象为:" + jp.getTarget());
    }
     
     
    @AfterReturning(pointcut="execution(* com.dong.model.*.*(..))",returning="rvt")
    public void log(JoinPoint jp, Object rvt){
         
        System.out.println("AfterReturning 增强处理: 获取目标方法的返回值 " + rvt);
        System.out.println("AfterReturning 增强处理: 被织入增强处理的目标方法为: " + jp.getSignature().getName());
        System.out.println("AfterReturning 增强处理: 目标方法的参数为: " + Arrays.toString(jp.getArgs()));
        System.out.println("AfterReturning 增强处理: 被织入增强处理的目标对象为 :"  + jp.getTarget());
    }
After和AfterReturning的顺序为什么会反了

下面是执行结果

Around 增强:执行目标方法之前, 模拟开始事务
Before 增强: 模拟执行权限检查
Before 增强: 被织入增强处理的目标方法为:  sayHello
Before 增强: 目标方法的参数是: [被改变的方法]
Before 增强: 被织入增强处理的目标对象时:  com.dong.model.Chinese@b35f26b
heoolo: 被改变的方法
Around 增强: 执行目标方法之后,模拟事务结束
After 增强处理:模拟方法结束后的释放资源
After 增强处理:被织入处理方法的目标方法为:sayHello
After 增强处理:目标方法的参数为:[Ljava.lang.Object;@2be548d
After 增强处理:被织入增强处理的目标对象为:com.dong.model.Chinese@b35f26b
AfterReturning 增强处理: 获取目标方法的返回值 null新增的内容
AfterReturning 增强处理: 被织入增强处理的目标方法为: sayHello
AfterReturning 增强处理: 目标方法的参数为: [被改变的方法]
AfterReturning 增强处理: 被织入增强处理的目标对象为 :com.dong.model.Chinese@b35f26b


不是应该AfterReturning在前吗

展开
收起
a123456678 2016-03-17 15:01:21 2875 0
1 条回答
写回答
取消 提交回答
  • Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字. 我们可以通过在@AspectJ的方法中实现org.springframework.core.Ordered 这个接口来定义order的顺序,order 的值越小,说明越先被执行。比如代码如下:          [java] view plain copy  /**  * @author HuifengWang  * aop面向切面编程  *  */   @Component   @Aspect   public class AspectJ4DataBase implements Ordered{    //拦截所有的service操作   @Pointcut("execution( * com.hc.shop.*.service.*.*(..))")   public void readMethod() {   }// 匹配所有的读取操作    @Before("readMethod()")   public void onlyReadPre(){   DataSourceContextHolder.setDataSourceType(DataSourceType.MYSQL);   System.out.println("数据库切换MYSQL");   }   @After("readMethod()")   public void onlyReadPast(){   DataSourceContextHolder.setDataSourceType(DataSourceType.ORACLE);   System.out.println("数据库切换回ORACLE");   }    @Override   public int getOrder() {   // TODO Auto-generated method stub   return 1;   }   }   在事务配置的地方也配置order 字段,代码如下: [html] view plain copy <!-- 注解方式配置事物 -->   <tx:annotation-driven transaction-manager="transactionManager" order="2"/>    这样就实现了我们自己写的aop在事务介入之前就执行了! 可以防止spring事务的失效。
    

    “答案来源于网络,供您参考” 希望以上信息可以帮到您!

    2019-09-27 20:33:51
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关实验场景

更多