【问题标题】:AspectJ join points to advice only "boundary" executions and callsAspectJ 连接点只建议“边界”执行和调用
【发布时间】:2015-09-12 11:50:20
【问题描述】:

1) 是否可以拦截针对(从外部到内部)一组类(或者可能是一个包,但不是子包)和外部调用(从这些类到该组外部)的执行(或调用)类),但不是“内部”执行/调用(从该组的任何类到同一组的任何类)仅使用切入点定义(即,建议中没有额外的 Java 代码)? 2) 是否可以将该组指定到外部文件中以在运行时加载(加载时间编织)?

我想要的是编写一个工具来在运行时应用给定方面,但开发人员可以在 JVM 启动时指定一组类(命令行或文本文件)。

我已经设法在建议中使用额外的 Java 反射代码来实现第 1 点,但这并不理想(慢),而且我不确定我是否可以从外部文件加载类/包名称并应用它们方面J:

private static final String PACKAGE_REGEX = "com.advisethispackage..*";
private static final String BEFORE_EXECUTION_AND_NEW_INVOCATION_FILTER = "((execution(* *(..))) || (execution(*.new(..)))) && within(" + PACKAGE_REGEX + ")";
private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && within(" + PACKAGE_REGEX + ")";

我尝试过使用 insidecode(显然我还没有真正理解),或者以这种方式排除调用...

private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && (!call(* " + WITHIN_REGEX + "(..))) && (!call(" + WITHIN_REGEX + ".new(..))) && within(" + WITHIN_REGEX + ")";

...但它未能排除一些同类调用。有什么想法吗?

我的 aop.xml 文件如下所示:

<aspectj>
  <aspects>
    <aspect name="org.my.aspects.RecordingAspect"/>
    <include within="org..*"/>
  </aspects>

  <weaver options="-verbose -debug -showWeaveInfo">
    <include within="com.advisethispackage..*"/>
    <include within="org.my.aspects..*"/>
  </weaver>
</aspectj>

我对 AOP 还很陌生,只知道 AspectJ,并且只使用了注解,而不是 AspectJ 编译器或 AJDT。 我在 Java 8 中使用 aspectj-1.8.6。


示例:我有 4 个班级(A、B、C、D)。 A 调用 B 上的方法,调用 C,调用 D。B 和 C 是我要建议的类(com.advisethispackage.B,com.advisethispackage.C),但 A 和 D 不是(com.dontadvisethispackage.A , com.dontadvisethispackage.D)。我的 RecordingAspect 建议只是打印出“在类 'X' 上调用方法”或“从类 'X' 调用方法到类 'Y'”。

录制时,我想输出为:

Invoked method on class 'B'
Invoking method from class 'C' to class 'D'

没有别的了。 我也在记录“之后”的时刻,它会打印出来......

Returning from invocation of method on class 'D' called by class 'C'
Returning from invocation of method on class 'B'

...但我想切入点定义应该是一样的。

谢谢

【问题讨论】:

    标签: java aspectj pointcut


    【解决方案1】:

    不知道你是否已经找到这个,但这是我为匹配你的情况而修改的两个切入点(使用 AspectJ 注释)

    @Pointcut("call(* com.advisethispackage..*.*(..)) && !withincode(* com.advisethispackage..*.*(..))")
    public void callFromOutsideToInside() {}
    
    @Before("call(* (!com.advisethispackage..*).*(..)) && withincode(* com.advisethispackage..*.*(..))")
    public void callFromInsideToOutside() {}
    

    如果你还想匹配构造函数:

    @Pointcut("call(com.advisethispackage..*.new(..)) && !withincode(* com.advisethispackage..*.*(..))")
    public void callFromOutsideToInside() {}
    
    @Before("call((!com.advisethispackage..*).new(..)) && withincode(* com.advisethispackage..*.*(..))")
    public void callFromInsideToOutside() {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 2020-09-29
      相关资源
      最近更新 更多