Dynamic Proxy API

Java platform has made significant improvement with the introduction of the Dynamic Proxy API. It can be used to create a type-safe proxy object for a list of interfaces without requiring pre-generation of the proxy class.

 

Proxy class

Before looking more about dynamic proxies, lets first look at proxy pattern which is one of the most frequently used structural pattern.

In general, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic.

A virtual proxy and access proxy are commonly used proxies. A virtual proxy is used to perform lazy or just-in-time instantiation of the real object.An access proxy is used to enforce a security policy on access to a service or data-providing object.

The following UML diagram shows the working of Proxy pattern.

proxy-pattern-structure

Figure: Proxy Pattern Structure

Here, whenever client makes request for doAction() method, ProxySubject forwards requests to RealSubject when appropriate, depending on the kind of proxy.

 

Dynamic Proxy Class

Oracle  has provided a very promising definition of dynamic proxy class which you can find at Oracle's API Docs. It states that "a dynamic proxy class is a class that implements a list of interfaces specified at runtime such that a method invocation through one of the interfaces on an instance of the class will be encoded and dispatched to another object through a uniform interface.

Method invocations on an instance of a dynamic proxy class are dispatched to a single method in the instance's invocation handler, and they are encoded with a java.lang.reflect.Method object identifying the method that was invoked and an array of type Object containing the arguments."

 

Implementation

To create an actual dynamic proxy class, all you need to do is implement the java.lang.reflect.InvocationHandler interface:

public Class MyDynamicProxyClass implements java.lang.reflect.InvocationHandler
{
  Object obj;
  public MyDynamicProxyClass(Object obj){ 
       this.obj = obj; 
  }
  public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
  {
    try {
      // put your logic here
    } catch (InvocationTargetException e) {
      throw e.getTargetException();
    } catch (Exception e) {
      throw e;
    }
    // return something
  }
}

Now, one thing you need to keep in mind while using dynamic proxy is that the proxy interface must be an interface. In other words, it cannot be a class (or an abstract class) or a primitive. 

public interface MyProxyInterface
{
    public Object MyMethod();
}

Now, one thing you need to keep in mind while using dynamic proxy is that the proxy interface must be an interface. In other words, it cannot be a class (or an abstract class) or a primitive. 

public interface MyProxyInterface
{
    public Object myMethod();
}

To construct a MyDynamicProxyClass for an implementation of the MyProxyInterface interface

MyProxyInterface foo = (MyProxyInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), Class[] { MyProxyInterface.class },new MyDynamicProxyClass(obj));

and call one of its methods:

foo.myMethod();

The above mentioned dynamic proxy constructs code can be made more managed in accordance with the Oracle's API doc.

 

Example

Consider we've an application that logs every method gets invoked by client.

The proxy interface is:

/**
 * Proxy interface
 */
public interface IVehicle {
    void start();
}

The implementation of the interface above is:

/**
 * Proxy interface implementation
 */
public class Car implements IVehicle {
    private String name;

    public Car(String name) {
        this.name = name;
    }

    public void start() {
        System.out.println("Car " + name + " started");
    }
}

Now, the dynamic proxy class is:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Dynamic Proxy class
 */
public class Logger implements InvocationHandler {
    private Object vehicle;

    public Logger(Object v) {
        this.vehicle = v;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Logger: "+ method.getName());
        Object object = method.invoke(vehicle,args);
        return object;
    }
}

Finally the client for our application is:

import java.lang.reflect.Proxy;

/**
 * Client
 */
public class Application {
    public static void main(String[] args) {
        IVehicle c = new Car("Herbie");
        ClassLoader cl = IVehicle.class.getClassLoader();
        IVehicle v1 = (IVehicle) Proxy.newProxyInstance(cl, new Class[]
                { IVehicle.class }, new Logger(c));
        v1.start();
    }
}

The output of the program is:

Logger: start
Car Herbie started

The output illustrates that proxy is being created dynamically and real subject is called through that proxy.

Abstract Factory Pattern
MVC Pattern