2
回答
spring 的aop顺序问题
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
@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在前吗




举报
plugin
发帖于3年前 2回/472阅
共有2个答案 最后回答: 3年前

除了调整两个方法的先后顺序以外,你可以让修改同一个参数,让两个方法的pointCut相同,然后用@Order调整他们的顺序.下面AfterReturn会先执行:

@AfterReturning("execution(* com.dong.model.*.*(..))")
    @Order(1)
    public void logAfterRtn(JoinPoint jp){
//      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("execution(* com.dong.model.*.*(..))")
    @Order(2)
    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());
    }



--- 共有 3 条评论 ---
plugin回复 @hao5ang : 我勒个去。原来如此。真是太感谢了 3年前 回复
hao5ang回复 @plugin : 版本问题.3.0.5调整方法顺序是可以的.我用了一个最新版的4.x试了一下,不可以.. 3年前 回复
plugin非常感谢,这样确实可以。 但是无论怎么调整方法的顺序都是AfterReturning在后 3年前 回复

参考一下Advice ordering这一节:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html

这两个顺序应该是不确定的.

--- 共有 2 条评论 ---
hao5ang回复 @plugin : 那个finally是一定执行的意思,是说无论方法是否抛出异常,After一定执行.你把After和AfterReturning两个方法顺序换一下,再测试,那么After就输出在后面了. 3年前 回复
plugin人家好像说after 是finally了啊。。不好意思。我英文不太好 3年前 回复
顶部