dillyg10
dillyg10

Reputation: 13

Listening for when a method is called in a class, and then possibly overriding it (java)

So, let's say I have 2 classes, Foo1 and Foo2, which is in a separate library.

Foo2 is a class that is already instantiated, and I cannot correctly reinstintate it as a subclass to override a method in Foo2.

Is there any way I can listen to a certain method that is called in Foo2, and then possibly cancel the execution of said method, and from there create another method. I understand if what I"m saying is confusing, hopefully I can get some help :).

    class Foo{

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

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

Obviously, the above code won't do anything, it is just simple an example of what I am looking for.

Upvotes: 0

Views: 2277

Answers (5)

valijon
valijon

Reputation: 1434

Assuming that you can subclass the type, the following code would work perfectly:

Foo foo = new Foo() {

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

Upvotes: 0

Rafa
Rafa

Reputation: 2027

In my opinion, to solve this issue you could use a third class to act as a Decorator/Proxy.

For instance, you can do something like:

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

Upvotes: 0

Totò
Totò

Reputation: 1854

you need a proxy on that object, and an interceptor on the method. There are a couple of ways to do it:

  1. If you have an interface you can use reflection and proxies and invocation handlers docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html.

  2. If you have a concrete class you can use CGLIB cglib.sourceforge.net to create an enhancer for your class

  3. If you are using Spring you can use the AOP http://static.springsource.org/spring/docs/2.5.5/reference/aop.html.

  4. You can also use AspectJ http://www.eclipse.org/aspectj/doc/next/progguide/ to do the same

    Cheers!

Upvotes: 5

user2570465
user2570465

Reputation: 2497

Depending on what you're trying to do, this might work:

If you had a boolean isX2Called in class Foo, when x2() is called, set isX2Called to true. Then in x(), you can check if isX2Called is true. If you ever want to reset, you can set isX2Called back to false. This might not work for all purposes though.

Upvotes: 0

user908627
user908627

Reputation:

If you can't somehow subclass Foo2 or modify the existing lib (in worst case you could decompile/modify/recompile) you could use aspectj to intercept calls.

You'd probably want to use load-time weaving for this purpose. Check out the general documentation for load-time weaving here: http://www.eclipse.org/aspectj/doc/next/devguide/ltw.html. It's a fairly involved procedure to add/configure aspectj though so I'd only recommend it as a last resort

Upvotes: 4

Related Questions