Java Dynamic Proxy

Dynamic proxying is used widely in the frameworks, so a basic understanding of the implementation can be helpfull to use those frameworks.

Of course, there can be a situation where a dynamic proxy implementation can be a good choice.

Here a simple example of a dynamic proxy implementation using Java 8

 


package com.ardevco;

/*
This is the interface that dynamic proxy will use
*/
@FunctionalInterface
public interface MyBeanInterface {
String myMethod(int i);
}


package com.ardevco;

/*
The actual implementation of the interface.
This implementation will never be reached by the client and will only be reachable by the proxy.
*/
public class MyBeanImpl implements MyBeanInterface {
public String myMethod(int i) {
return String.format("%d fom %s",i*i, this);
}
}

 


package com.ardevco;

/*
MyBeanInvocationHandler

This class is the implementation of the InvocationHandler interface.
The InvocationHandler interface is used to forward methods invokes.
The invoke method can implement the method self or delegate the invocation to the real implementation class.
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyBeanInvocationHandler implements InvocationHandler {

private static final String TO_STRING = "toString";
private static final String HASH_CODE = "hashCode";
private static final String EQUALS = "equals";
private Object myBeanImp;

public MyBeanInvocationHandler(Object impl) {
this.myBeanImp = impl;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class == method.getDeclaringClass())
return processObjectMethods(proxy, method, args); // process Object methods invokes using the real proxy class
return method.invoke(myBeanImp, args);
}

private Object processObjectMethods(Object proxy, Method method, Object[] args) {
String name = method.getName();

if (EQUALS.equals(name)) {
return proxy == args[0];
}
else if (HASH_CODE.equals(name)) {
return System.identityHashCode(proxy);
}
else if (TO_STRING.equals(name)) {
return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy)) +
", with InvocationHandler " + this;
}
else {
throw new IllegalStateException(String.valueOf(method));
}
}
}


package com.ardevco;
import java.lang.reflect.*;
import java.util.stream.IntStream;

public class Client {
public static void main(String args[]) {

MyBeanInterface myBeanInterface = (MyBeanInterface)    Proxy.newProxyInstance(MyBeanInterface.class.getClassLoader(), new     Class<?>[] { MyBeanInterface.class }, new MyBeanInvocationHandler(new MyBeanImpl()));
MyBeanInterface myBeanInterface2 = new MyBeanImpl();

System.out.printf("myBeanInterface.hashCode(): %H%n", myBeanInterface);
System.out.printf("myBeanInterface.hashCode(): %H%n", myBeanInterface2);
System.out.printf("myBeanInterface.equals(myBeanInterface): %B%n", myBeanInterface.equals(myBeanInterface));
System.out.printf("myBeanInterface.equals(myBeanInterface2): %B%n", myBeanInterface.equals(myBeanInterface2));
System.out.printf("myBeanInterface.toString(): %s%n", myBeanInterface);

IntStream.range(95, 100).forEach(i -> System.out.printf("myBeanInterface.myMethod(x): %s%n", myBeanInterface.myMethod(i)));
}
}

 

If you run this program, the console output is:


myBeanInterface.hashCode(): 135FBAA4
myBeanInterface.hashCode(): 45EE12A7
myBeanInterface.equals(myBeanInterface): TRUE
myBeanInterface.equals(myBeanInterface2): FALSE
myBeanInterface.toString(): com.sun.proxy.$Proxy0@135fbaa4, with InvocationHandler com.ardevco.MyBeanInvocationHandler@330bedb4
myBeanInterface.myMethod(x): 9025 fom com.ardevco.MyBeanImpl@3f99bd52
myBeanInterface.myMethod(x): 9216 fom com.ardevco.MyBeanImpl@3f99bd52
myBeanInterface.myMethod(x): 9409 fom com.ardevco.MyBeanImpl@3f99bd52
myBeanInterface.myMethod(x): 9604 fom com.ardevco.MyBeanImpl@3f99bd52
myBeanInterface.myMethod(x): 9801 fom com.ardevco.MyBeanImpl@3f99bd52

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s