spring aop 利用JoinPoint获取参数的值和方法名称

1.Advice的主要类型:

  • 前置通知 @Before:该注解标注的方法在业务模块代码执行之前执行,其不能阻止业务模块的执行,除非抛出异常;
  • 返回通知 @AfterReturning:该注解标注的方法在业务模块代码执行之后执行;
  • 异常通知 @AfterThrowing:该注解标注的方法在业务模块抛出指定异常后执行;
  • 后置通知 @After:该注解标注的方法在所有的Advice执行完成后执行,无论业务模块是否抛出异常,类似于finally的作用;
  • 环绕通知 @Around:该注解功能最为强大,其所标注的方法用于编写包裹业务模块执行的代码,其可以传入一个ProceedingJoinPoint用于调用业务模块的代码,无论是调用前逻辑还是调用后逻辑,都可以在该方法中编写,甚至其可以根据一定的条件而阻断业务模块的调用;
  • @DeclareParents:其是一种Introduction类型的模型,在属性声明上使用,主要用于为指定的业务模块添加新的接口和相应的实现。
  • @Aspect:严格来说,其不属于一种Advice,该注解主要用在类声明上,指明当前类是一个组织了切面逻辑的类,并且该注解中可以指定当前类是何种实例化方式,主要有三种:singleton、perthis和pertarget,具体的使用方式后面会进行讲解。

        这里需要说明的是,@Before是业务逻辑执行前执行,与其对应的是@AfterReturning,而不是@After,@After是所有的切面逻辑执行完之后才会执行,无论是否抛出异常。

环绕通知顺序:

2.切点表达式

博客地址:https://www.cnblogs.com/zhangxufeng/p/9160869.html

 

3.spring aop 利用JoinPoint获取参数的值和方法名称:

@Aspect
@Component
public class AspectCeShi {

    @Pointcut("@within(com.ceshi.demo.demo.pingan.DynamicSwitchDataSource) || " +
            "@annotation(com.ceshi.demo.demo.pingan.DynamicSwitchDataSource)")
    public void pointcut(){}

    @Before("pointcut()")
    public void doBefore(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        Signature signature = joinPoint.getSignature();
        Object target = joinPoint.getTarget();
        Object aThis = joinPoint.getThis();

        System.out.println(Arrays.toString(args));
        System.out.println(signature);
        System.out.println(target.toString());
        System.out.println(aThis.toString());

    }
}

AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕增强时,使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口。任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息。我们先来了解一下这两个接口的主要方法: 
1)JoinPoint 

# 1.获取连接点方法运行时的入参列表; 
java.lang.Object[] getArgs()

# 注:获取的是自定义注解方法的参数列表,以数组方式呈现,如果在运行下列方法时参数为123,则获取的数组#     里面只有参数123
    @DynamicSwitchDataSource
    public void ceShiDao(String bb){
        System.out.println("Dao方法执行了");
    }

# 2.获取连接点的方法签名对象; 
Signature getSignature()

# 注:获取的是当前自定义注解(连接点)的方法签名对象
# 方法对象为:void com.ceshi.demo.demo.pingan.CeShiDao2.ceShiDao(String)
    @DynamicSwitchDataSource
    public void ceShiDao(String bb){
        System.out.println("Dao方法执行了");
    }

# 3.获取连接点所在的目标对象; 
java.lang.Object getTarget()

# 注:获取的是当前自定义注解(连接点)方法所在的这个类
# 连接点所在的目标对象:CeShiDao2
    public class CeShiDao2 {
        @DynamicSwitchDataSource
        public void ceShiDao(String bb){
            System.out.println("Dao方法执行了");
        }
    }

# 4.获取代理对象本身;
# 代理对象本身:CeShiDao2@173013d4
java.lang.Object getThis()


2)ProceedingJoinPoint 
ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法: 

# 通过反射执行目标对象的连接点处的方法;
java.lang.Object proceed() throws java.lang.Throwable


# 通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。  
java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章