A Java dynamic proxy class is a type of “add-on” on top of the original class, which allows the Java developers to change the behaviors of the original class as per requirement. Suppose, if you are using a class as part of an off-the-shelf JAR library and you cannot simply rewrite its source code but you also need to change how this class behaves.
Table of Contents
For instance, you don’t know which method of this class might be called on your object, but you want to output an important “acknowledgment” message. Java Dynamic Proxies is the ideal solution for this problem.
In this article, we will learn all about Java dynamic proxies. What are the Java dynamic proxies? how do they work? and when you should be ideally using it in your Java code.
Java Dynamic Proxies are part of the Java proxy design pattern. It allows the creation of proxy objects when a program requires to extend or modify some functionalities of an already existing class. In that case, A proxy object is instantiated instead of the original one. Commonly, the proxy objects have the same methods as the original object and the original class is extended in a Java proxy class. The Java dynamic proxies have a handle over the original objects and original class methods can also be called by that.
Due to this, the proxy classes can implement a lot of different things in a very convenient way, few examples of such things include:
The above-mentioned applications cannot be done without modifying the original code of the class which makes them the ideal applications for Java dynamic proxies.
In such applications, the proxy class does not directly implement the functionality upon the original class objects. Following the single responsibility principle, the proxy class only creates a proxy and the actual behavior is modified in the handlers. When the proxy object is invoked instead of the original object, the Java dynamic proxies then decide whether if it has to invoke the original method or the handler. The handler may do its extended tasks and it can also call the original method to perform the original tasks as well.
It is a relatively advanced topic in Java Programming language because it requires some extensive knowledge of Java. The developers planning to work with Java dynamic proxies must know about the use of the reflection class or the bytecode manipulation or how to compile the Java code that is generated dynamically. To create the bytecode, you should learn how to use cglib or bytebuddy or the built-in Java compiler, first.
See Also: Java Scanner – Comprehensive Guide with Examples
InvocationHandler is a special interface that allows us to intercept any method call to the object and add the additional behavior that we need. We first need to create our interceptor by creating a class that implements this interface. It only contains one method: invoke(), in which the original object is passed as an argument, to be proxied.
When we think about the proxy classes and the handlers that are invoked by them, it is understood that why the separation of responsibilities is very important here. The proxy class is always generated during the run-time, but the handler invoked by the proxy class can be coded with the source code and it can be compiled along with the code of the whole program during compile time.
Proxy classes, as well as instances of them, are created using a static method of the class java.lang.reflect.Proxy. It is part of the JDK and can create a proxy class or directly an instance of it. The use of the Java built-in proxy is relatively easier. All you need to do is implement a java.lang.InvocationHandler, so that the proxy objects can later invoke it. After this, the invoke() method from Invocation Handler is called.
Another method, the Proxy.getProxyClass method returns the java.lang.Class object for a proxy class given a class loader and an array of interfaces.
According to the Dynamic Proxy classes Java documentation, there are some restrictions on the parameters that must be passed to Proxy.getProxyClass:
This code below demonstrates all the discussed points to use of Java Dynamic proxies in your code:
1. package proxy; 2. 3. import java.lang.reflect.InvocationHandler; 4. import java.lang.reflect.InvocationTargetException; 5. import java.lang.reflect.Method; 6. import java.lang.reflect.Proxy; 7. 8. public class ProxyDemo { 9. 10. interface If { 11. void originalMethod(String str); 12. } 13. 14. static class Original implements If { 15. public void originalMethod(String str) { 16. System.out.println(str); 17. } 18. } 19. 20. static class Handler implements InvocationHandler { 21. private final If original; 22. 23. public Handler(If original) { 24. this.original = original; 25. } 26. 27. public Object invoke(Object proxy, Method method, Object[] args) 28. throws IllegalAccessException, IllegalArgumentException, 29. InvocationTargetException { 30. System.out.println("Before the proxy: "); 31. method.invoke(original, args); 32. System.out.println("After the proxy: "); 33. return null; 34. } 35. } 36. 37. public static void main(String[] args){ 38. Original original = new Original(); 39. Handler handler = new Handler(original); 40. If a = (If) Proxy.newProxyInstance(If.class.getClassLoader(), 41. new Class[] { If.class }, 42. handler); 43. a.originalMethod("Hello"); 44. } 45. 46. } 47.
Now, if the handler wants to invoke the original method on the original object, first, it must have the access to it. This will not be provided by the Java proxy implementation. The developer has to pass this argument to the handler instance manually in the code.
You must have noted that an object often named “proxy” is passed as an argument to the invocation handler. This is the proxy object that is generated by the Java reflection dynamically and not the object we want to proxy. Due to this, developers use a separate handler object for each original class or they can also use some shared object that knows which original object is to be invoked if there is any method to invoke at all. You can also create an invocation handler and a proxy of an interface that does not have any original object. You don’t need any class to implement the interface in the code. The dynamically created proxy class will implement the interface automatically.
The Java dynamic proxies are actively used in popular technologies. One of the common usages is seen in security frameworks.
We have covered all the basics of the Java dynamic proxy. It is a quite functional yet very intricate tool for a Java developer but if used correctly it can be a fine addition to your java toolkit.
Create a free profile and find your next great opportunity.
Sign up and find a perfect match for your team.
Xperti vets skilled professionals with its unique talent-matching process.
Connect and engage with technology enthusiasts.
© Xperti.io All Rights Reserved
Privacy
Terms of use