Dynamic Proxy with Proxy and InvocationHandler in Java

By Arvind Rai, 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)
 
To understand the arguments, I will take the example that I have an interface names as Task and its implementation class is TaskImpl. Dynamic proxy class will be created of TaskImpl class. Now understand how the argument will be passed in <>Proxy. newProxyInstance() method.
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)
 
The description of arguments is given below.
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);
}
 
The sample implementation of the interface is given below.
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;
	}
}
 
Find the InvocationHandler implementation. invoke() method has be defined.
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;
    }
}
 
Create a factory class to get dynamic proxy class.
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));
	}
}
 
Now this is the time to test our dynamic proxy class by calling its method.
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));
	}
}
 
Find the output. Output
...set Method Executing...
Test Data is saved
...get Method Executing...
50
 

What if when Proxy Interfaces have Multiple Duplicated Methods?

To create dynamic proxy class, we need to pass an array of all those interfaces which will be implemented by our dynamic class. Suppose we pass two interfaces having duplicate methods. These duplicate methods will be same in arguments but will differ in return type. Now what will be of those duplicate methods while invoking methods of the dynamic proxy class? Here the order of those methods will be significant and foremost interface method will be invoked.
POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us