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