SpringAOP通知细节-多个切面及排序

Posted IT老刘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAOP通知细节-多个切面及排序相关的知识,希望对你有一定的参考价值。

1.同一个切面类多个相同通知

举例:在同一个类中有两个类型相同通知,那么执行顺序呢?

 /**
     * 01-前置通知:在目标方法之前被执行!
     */
    @Before(value = "execution(* com.bruce.service.impl.*.*(..))")
    public void openTx1(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();//被拦截的方法的方法名
        Object[] args = joinPoint.getArgs(); //被拦截的方法的参数
        //封装的目标方法的信息
        System.out.println("前置openTx1-开启事务....方法名:"+name+",参数是:"+ Arrays.toString(args));
    }

    @Before(value = "execution(* com.bruce.service.impl.*.*(..))")
    public void openTx2(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();//被拦截的方法的方法名
        Object[] args = joinPoint.getArgs(); //被拦截的方法的参数
        //封装的目标方法的信息
        System.out.println("前置openTx2-开启事务....方法名:"+name+",参数是:"+ Arrays.toString(args));
    }

运行结果:

那么这两个方法的顺序如何确定呢?

/**
 * 01-前置通知:在目标方法之前被执行!
 */
@Before(value = "execution(* com.bruce.service.impl.*.*(..))")
public void bopenTx1(JoinPoint joinPoint){
    String name = joinPoint.getSignature().getName();//被拦截的方法的方法名
    Object[] args = joinPoint.getArgs(); //被拦截的方法的参数
    //封装的目标方法的信息
    System.out.println("前置openTx1-开启事务....方法名:"+name+",参数是:"+ Arrays.toString(args));
}

@Before(value = "execution(* com.bruce.service.impl.*.*(..))")
public void aopenTx2(JoinPoint joinPoint){
    String name = joinPoint.getSignature().getName();//被拦截的方法的方法名
    Object[] args = joinPoint.getArgs(); //被拦截的方法的参数
    //封装的目标方法的信息
    System.out.println("前置openTx2-开启事务....方法名:"+name+",参数是:"+ Arrays.toString(args));
}

运行结果:

2.Spring之AOP多切面通知方法的运行顺序

指定切面的优先级

  • 在同一个连接点上应用不止一个切面时,除非明确指定,否则它们的优先级是不确定的。
  • 切面的优先级可以通过实现Ordered接口或利用@Order注解指定。
  • 实现Ordered接口,getOrder()方法的返回值越小,优先级越高。
  • 若使用@Order注解,序号出现在注解中

@Order:注解@Order不能决定Spring容器加载Bean的顺序,只能决定执行顺序

2.Order注解修饰方法

public class Cat {

    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Cat(){

    }

    public Cat(String name){
        this.name=name;
        System.out.println(name);
    }

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\\'' +
                '}';
    }
}
package com.bruce.config;

import com.bruce.pojo.Cat;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import java.util.List;

@Configuration
public class CatConfig {

    @Bean
    @Order(3)
    public Cat cat1(){
        return new Cat("cat1()");
    }


    @Bean
    @Order(4)
    public Cat cat2(){
        return new Cat("cat2()");
    }

    @Bean
    @Order(1)
    public Cat cat3(){
        return new Cat("cat3()");
    }

    @Bean
    public Cat Cat4(List<Cat> cats){
        System.out.println(cats);
        for (Cat cat : cats) {
            System.out.println("--->"+cat);
        }
        return cats.get(0);
    }

}

运行结果:

以上是关于SpringAOP通知细节-多个切面及排序的主要内容,如果未能解决你的问题,请参考以下文章

SpringAOP 面向切面编程-后置通知

SpringAOP 面向切面编程-前置通知

SpringAOP 面向切面编程-环绕通知(掌握)

SpringAOP 面向切面编程-异常+最终通知(了解)

图文并茂!!!一文搞懂SpringAOP(面向切面编程)

图文并茂!!!一文搞懂SpringAOP(面向切面编程)