侦听类中何时调用方法,然后可能重写它(java)

侦听类中何时调用方法,然后可能重写它(java),java,overriding,Java,Overriding,假设我有两个类,Foo1和Foo2,它们在一个单独的库中 Foo2是一个已经实例化的类,我无法正确地将其作为子类重新着色以覆盖Foo2中的方法 有没有什么方法可以让我监听Foo2中调用的某个方法,然后可能取消所述方法的执行,并从中创建另一个方法。我明白如果我说的话令人困惑,希望我能得到一些帮助: class Foo{ void x(){ if (Foo2.x2().called){ //do stuff } } } class

假设我有两个类,Foo1和Foo2,它们在一个单独的库中

Foo2是一个已经实例化的类,我无法正确地将其作为子类重新着色以覆盖Foo2中的方法

有没有什么方法可以让我监听Foo2中调用的某个方法,然后可能取消所述方法的执行,并从中创建另一个方法。我明白如果我说的话令人困惑,希望我能得到一些帮助:

    class Foo{

    void x(){
    if (Foo2.x2().called){
    //do stuff
    }
    }
    }

    class Foo2{
    void x2(){
    //Stuff done here...
    }
    }

显然,上面的代码不会做任何事情,它只是我正在寻找的一个简单示例

如果您无法在最坏的情况下将Foo2子类化或修改现有库,那么您可以反编译/修改/重新编译,您可以使用aspectj拦截调用


为此,您可能希望使用加载时编织。请在此处查看加载时编织的一般文档:。添加/配置aspectj是一个相当复杂的过程,因此我只建议将其作为最后的手段

在我看来,要解决这个问题,您可以使用第三个类作为装饰器/代理

例如,您可以执行以下操作:

class FooManager {

  private Foo1 f1;

  private Foo2 f2;

  private boolean canExecuteFooMethods(){
     // Evaluate if should run any Foo1 or Foo2 method
  }
  public void foo1Method(){
    if(canExecuteFooMethods()){
      f1.x();
    }
  }

  public void foo2Method(){
    if(canExecuteFooMethods()){
      f2.x();
    }
  }
}

根据您尝试执行的操作,这可能会起作用:


如果在类Foo中调用了一个布尔值isx2,那么在调用x2时,将isX2Called设置为true。然后在x中,您可以检查isX2Called是否为true。如果要重置,可以将isx2callback设置为false。但这可能并不适用于所有目的。

您需要在该对象上使用代理,在该方法上使用拦截器。有几种方法可以做到这一点:

如果您有一个接口,您可以使用反射和代理以及调用处理程序docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html

如果您有一个具体的类,那么可以使用CGLIB CGLIB.sourceforge.net为您的类创建增强器

如果您使用的是Spring,那么可以使用AOP

您也可以使用AspectJ来做同样的事情

干杯


假设您可以对该类型进行子类化,那么以下代码将非常有效:

Foo foo = new Foo() {

    @Override
    public void someMethod() {
        super.someMethod();
        //your logic here (listen, hook, spy, override, etc)
    }
}

您是否有机会展示一些代码,让我们更好地了解您想要做什么?另外,Foo1在哪里发挥作用?好吧,我不能给出太多的硬示例,不是因为我不想给出代码。。。但是因为它与一个时髦的库有关,无论如何,让我快速编辑上面的帖子,展示我所说的。利用这个:在设计模式的意义上,门面不是你所说的。它可以更好地描述为代理或装饰好的一点,我认为这将是一个很好的候选人装饰。我想知道你是否愿意给出一个使用CGLIB的例子,我看了文档,我只是有点困惑。谢谢