Dynamic Proxy with Proxy and InvocationHandler in Java
March 31, 2014
A proxy calls object method indirectly through the proxy object. java.lang.reflect API provides a class as Proxy and an interface as InvocationHandler. Together these two API creates dynamic proxy class. Proxy class creates the dynamic proxy class on the basis of given parameters. InvocationHandler invokes the methods of dynamic proxy class. All these happening will be discussed below in detail with an example.
Proxy Class in Java
java.lang.reflect.Proxy is a class that provides static methods to create Dynamic Proxy class. There is a method as newProxyInstance() inside Proxy class which is defined as below.public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
1. ClassLoader : This class loader will define the dynamic proxy class. Class loader can be obtained by class or interface whose dynamic proxy is being created. If we try to get it by interface, call it a as below
Task.class.getClassLoader()and if we have class instance as ob of TaskImpl then class loader will be obtained as
ob.getClassLoader()2. The second argument needs the array of all the interfaces which will be implemented by dynamic proxy class.
3. Pass the instance of class which is implementing java.lang.reflect.InvocationHandler.
Find the properties of dynamic proxy class.
1. A proxy class is public and final. It cannot be an abstract class.
2. Each proxy class extends java.lang.reflect.Proxy.
3. If there is non-public interface in the list passed to create dynamic proxy, then that interface must be in the same package otherwise it will not be accessible
4. Each proxy class has one public constructor that takes one argument. By this constructor InvocationHandler instance is set.
5. Every proxy class will be associated with a InvocationHandler.
InvocationHandler in Java
InvocationHandler is an interface in java.lang.reflect package. InvocationHandler is implemented by a user class to invoke method of dynamic proxy class. The syntax of invoke method is as below.Object invoke(Object proxy, Method m, Object[] args)
Object : This is the proxy instance on which method is invoked.
Method: This corresponds to interface method which is invoked on proxy instance.
Object[]: It contains an array of arguments passed in method invocation.
Example to Create Dynamic Proxy Class
Now we will discuss the example to create the dynamic proxy class.This is the sample interface.
Task.java
package com.concretepage.proxy; public interface Task { public void setData(String data); public int getCalData(int x); }
TaskImpl.java
package com.concretepage.proxy; public class TaskImpl implements Task { @Override public void setData(String data) { System.out.println(data+ " Data is saved"); } @Override public int getCalData(int x) { return x*10; } }
MyInvocationHandler.java
package com.concretepage.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler{ private Object obj; public MyInvocationHandler(Object obj) { this.obj = obj; } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Object result; try{ if(m.getName().indexOf("get")>-1){ System.out.println("...get Method Executing..."); }else{ System.out.println("...set Method Executing..."); } result = m.invoke(obj, args); } catch (InvocationTargetException e) { throw e; } catch (Exception e) { throw e; } return result; } }
package com.concretepage.proxy; import java.lang.reflect.Proxy; public class ProxyFactory { public static Object newInstance(Object ob) { return Proxy.newProxyInstance(ob.getClass().getClassLoader(), new Class<?>[] { Task.class }, new MyInvocationHandler(ob)); } }
Test.java
package com.concretepage.proxy; public class Test { public static void main(String[] args) { Task task = (Task)ProxyFactory.newInstance(new TaskImpl()); task.setData("Test"); System.out.println(task.getCalData(5)); } }
...set Method Executing... Test Data is saved ...get Method Executing... 50