当前位置: 首页 > 面试题库 >

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

安轶
2023-03-14
问题内容

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

我以为是这样的:

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

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

指向对象的切入点初始化,因此我可以将这些方法直接注入到每个其他对象的对象中。

但是,它不起作用。你知道为什么吗?还是另一种方法可以如何100%确保每个初始化的对象都将成为切入点?* .new不适用于String,List等。

谢谢!


问题答案:

用户selig是正确的:您可能不想截取 所有 对象,尤其是JDK /
JRE类中的对象。但是,对于它的价值而言,这里是对什么有效,如何以及什么无效的解释:

一些驱动程序应用程序:

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);
    }
}

编织驱动程序应用程序的输出:

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

说明:

AspectJ中有不同的编织类型:

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

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

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



 类似资料:
  • 对象的切入点初始化,所以我可以直接将这些方法注入到作为每一个其他对象的一部分的对象中。 然而,它不起作用。你知道为什么吗?或者有什么其他方法可以100%地确保每个初始化的对象都是切入点?*.new不适用于字符串、列表等内容。 谢谢!

  • 这就是我的目标: 这是我的Aspect类: 如何为构造函数对象创建切入点?

  • 我就是不明白为什么我的切入点不起作用。编译器并没有给出任何警告,所以我无法解释它为什么不工作。我正在maven javafx应用程序中使用aspectjrt 1.7.2和aspectjtools 1.7.0。 我的样子是这样的 我的电影方面位于包主要。模型 下面是对我的代码中实际发生的事情的一点解释 当我的gui加载时,我初始化MainFrame类。在此之前,另一个方面加载所有电影对象。然后,当主

  • 类 类是对某一事物的抽象描述,具体地讲,类是C++中的一种构造的数据类型。它即可包含描述事物的数据,又可包含处理这些数据的函数,类在程序运行时是被用作样板来建立对象的。所以要建立对象,首先必须定义类。 定义类 定义一个类的一般格式为: class 类名{     private:         成员表1;     public:         成员表2;     protected:     

  • 是否有一种方法可以使用spring来指向cut hibernate实体。 这是我发现的,但没有解决办法

  • 在尝试向CDI bean(ApplicationScoped)的构造函数中注入参数时,我遇到了以下问题: 但是,我在类上确实有一个可注入的构造函数: 有什么想法这里出了什么问题吗?