In class today, we were talking about reflection in Java programming. A part of the lesson today was about using InvocationHandlers in Java, rather than just implementing an interface. When I asked the teacher what the advantages were of using an invocation handler, there wasn't a clear answer. So let's say we have an interface Plugin
public interface Plugin {
void calculate(double a, double b);
String getCommand();
}
you can easily implement this interface in a class Multiply
public class Multiply implements Plugin {
@Override
public void calculate(double a, double b){
return a * b;
}
@Override
public String getCommand(){
return "*";
}
}
Then why would I prefer another implementation using an InvocationHandler?
public class MyMock {
public static Object createMock(Class myClass) {
InvocationHandler handler = new MyInvocationHandler();
Object result = Proxy.newProxyInstance(myClass.getClassLoader(), new Class[]{myClass}, handler);
return result;
}
}
Thanks in advance :)
Proxy is a dynamic proxy, allowing you to alter the behaviour of objects at runtime instead of having to decide it at compile-time.
For example, let's say we want to return only nulls during the night. If you were to implement it statically, you would need to write the logic into all the classes with something like
if(isNight())
return null;
return normalValue;
This requires that you can actually change the class, and you would need to change all the classes.
However with a Proxy
, you can write the above logic into the InvocationHandler
and the normal classes won't even know that their values aren't used during the night. Instead of the original class, your code is now using the dynamic proxy, but it won't know the difference.
This also allows you to have multiple InvocationHandlers
, so you could run your code with parameters to decide if you want to log calls, prevent calls for security reasons, or any other such thing, which would be quite impossible to do with static implementations.
You're unlikely to use those classes directly though, as they're quite low level. However AOP uses either dynamic proxies or bytecode manipulation to achieve its task. If you've ever used Spring, you've most likely used an InvocationHandler
without knowing it. When you put @Transactional
on a method, an InvocationHandler
is what will intercept the method call and start (and end) the transaction for you.