Reputation: 13
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
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
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
Reputation: 1854
you need a proxy on that object, and an interceptor on the method. There are a couple of ways to do it:
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.
If you have a concrete class you can use CGLIB cglib.sourceforge.net to create an enhancer for your class
If you are using Spring you can use the AOP http://static.springsource.org/spring/docs/2.5.5/reference/aop.html.
You can also use AspectJ http://www.eclipse.org/aspectj/doc/next/progguide/ to do the same
Cheers!
Upvotes: 5
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
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