列出Spring面向方面编程中的所有连接点

时间:2016-11-18 08:59:14

标签: spring aop spring-aop

以某种方式可以在Spring的面向方面编程中列出与给定Pointcut匹配的所有Joinpoints。 我猜spring有一些注册表,其中所有Joinpoints都在运行时。

e.g。对

@Pointcut("execution(* transfer(..))")

某个地方应该有一个列表,其中包含所有被调用的方法" transfer"

1 个答案:

答案 0 :(得分:1)

我不知道Spring如何在内部完全处理AOP,但我知道它在运行时会创建动态代理(JDK或CGLIB类型)。因此,除非在生成报告时已经加载了所有目标类/接口,否则可能没有完整的列表。

但是我有一个优雅的解决方法:只是为了生成报告,使用纯AspectJ编译方面(AspectJ语法基本上是Spring AOP的超集),使用此选项为AspectJ编译器 ajc

-showWeaveInfo      display information about weaving

它将列出所有编织的连接点。对于静态确定的连接点,例如execution(),这是理想的。动态连接点如cflow()cflowbelow()(两者都不受Spring AOP支持)和if()只能在运行时进行评估,在这种情况下,编织的连接点数比实际使用的更多稍后在运行时,只是为了安全起见,不要错过任何可能的连接点。

此外,在使用AJDT(AspectJ开发工具)的Eclipse中,您可以使用很好的交叉引用视图,您可以在其中列出并动态导航从切入点到受影响的连接点,反之亦然。

给它一个旋转,祝你好运!但也许有人知道一个纯粹的Spring解决方案。我没有,因为我从未使用过Spring。

P.S。:这是纯粹的AspectJ中的一个小例子:

Java类:

package de.scrum_master.app;

public class Application {
    public int transfer() { return 11; }
    public void transfer(int number) { }
}
package de.scrum_master.app;

public class Whatever {
    public String transfer(int number) { return "foo"; }
    public void transfer(String text) { }
}

<强>方面:

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class TransferInterceptor {
    @Before("execution(* transfer(..))")
    public void intercept(JoinPoint thisJoinPoint) {
        System.out.println(thisJoinPoint);
    }
}

编译器输出-showWeaveInfo

Join point 'method-execution(java.lang.String de.scrum_master.app.Whatever.transfer(int))' in Type 'de.scrum_master.app.Whatever' (Whatever.java:4) advised by before advice from 'de.scrum_master.aspect.TransferInterceptor' (TransferInterceptor.aj:10)
Join point 'method-execution(void de.scrum_master.app.Whatever.transfer(java.lang.String))' in Type 'de.scrum_master.app.Whatever' (Whatever.java:5) advised by before advice from 'de.scrum_master.aspect.TransferInterceptor' (TransferInterceptor.aj:10)
Join point 'method-execution(int de.scrum_master.app.Application.transfer())' in Type 'de.scrum_master.app.Application' (Application.java:4) advised by before advice from 'de.scrum_master.aspect.TransferInterceptor' (TransferInterceptor.aj:10)
Join point 'method-execution(void de.scrum_master.app.Application.transfer(int))' in Type 'de.scrum_master.app.Application' (Application.java:5) advised by before advice from 'de.scrum_master.aspect.TransferInterceptor' (TransferInterceptor.aj:10)