gpt4 book ai didi

java - 构造函数对象上的 AspectJ 切入点

转载 作者:搜寻专家 更新时间:2023-11-01 01:03:53 29 4
gpt4 key购买 nike

我需要使用 AspectJ 向每个初始化对象注入(inject)一些方法。

我想用这个:

pointcut vistaInjection(Object o)
: initialization(java.lang.Object.new() )
&& target(o)
&& !within(objectAspect);

before(Object o): methodInjection(o){System.err.println("INIT");}

切入点初始化对象,这样我就可以将这些方法直接注入(inject)到属于每个其他对象的对象中。

但是,它不起作用。你知道为什么吗?或者有什么其他方法可以 100% 确定每个初始化的对象都将被切入点? *.new 不适用于字符串、列表和其他内容。

谢谢!

最佳答案

用户 selig 是对的:您可能不想拦截所有 对象创建,尤其是 JDK/JRE 类中的对象创建。但对于它的值(value),这里有一个解释,说明什么有效,什么无效:

一个小的驱动程序应用程序:

public class Application {
public static void main(String[] args) {
new Application();
new String();
}
}

具有不同类型的构造函数相关切入点/建议的方面:

public aspect ObjectCreationAspect {
before() : preinitialization(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}

before() : initialization(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}

before() : call(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}

before() : execution(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}
}

woven 驱动程序应用程序的输出:

call(Application())
preinitialization(Application())
initialization(Application())
execution(Application())
call(java.lang.String())

解释:

AspectJ 中有不同类型的编织:

  • 编译时织入(CTW):只能织入由ajc(AspectJ 编译器)编译的类。这不包括 JDK/JRE 类以及您不从源代码编译的第 3 方库。上面的示例输出显示了编译时织入的效果。
  • 二进制编织 (BW):AspectJ 编译器用于将方面代码直接编译为现有的字节代码。这适用于您自己的预编译应用程序类以及第 3 方库。理论上,如果您将 rt.jar 放在 AspectJ 编译器的路径中,它也适用于 JDK/JRE 类。 JDK/JRE 编织有点棘手,但我以前做过。您可以生成一个新编织的 rt.jar 版本,或者只是一个带有一些编织 JDK 类的小 JAR 文件,然后在启动您的应用程序时将其添加到 JDK/JRE 的引导类路径中。
  • 加载时编织 (LTW):基本上这是 BW,但在类加载期间动态完成。在此 AspectJ 场景中,您只能编织在方面编织器的影响下由类加载器加载的类。因此,它适用于您自己的代码和第 3 方库,但通常不适用于在加载切面编织器之前加载的 JDK/JRE 引导类。这是一个先有鸡还是先有蛋的问题:编织器需要 JRE 在加载之前运行,但是为了编织 JRE 类,编织器必须在这些类被引导之前就已经存在。

现在您可以轻松地从您自己的代码或编织的第 3 方代码中拦截对 JDK/JRE 构造函数的调用,正如您在日志输出行中看到的那样 call(java .lang.String())。但是,您无法拦截从 JRE 类到 JRE 类的内部调用。

说了这么多我真的很想知道你想做什么可怕的事情。我的意思是,你解释一下,这听起来像是一个巨大的设计错误。或者您想重新发明轮子并编写某种已经存在的分析器或调试器。您对拦截每个对象创建有什么期望?它会极大地降低您的应用程序速度,显着增加内存消耗并创建更多对象,如果只是您正在记录的字符串。请重新考虑并尝试考虑您真正想做的事情。也许那时我们可以建议一种实现目标的明智方法。

关于java - 构造函数对象上的 AspectJ 切入点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17338788/

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