gpt4 book ai didi

java - AspectJ join 只指向通知 "boundary"执行和调用

转载 作者:太空宇宙 更新时间:2023-11-04 13:27:06 25 4
gpt4 key购买 nike

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

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

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

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。我正在将方面j-1.8.6 与 Java 8 结合使用。

<小时/>

示例:我有 4 个类(class)(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'

...但我认为切入点定义应该是相同的。

谢谢

最佳答案

不知道您是否已经找到了这个,但这是我为匹配您的情况而调整的两个切入点(使用 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() {}

关于java - AspectJ join 只指向通知 "boundary"执行和调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32538441/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com