August 13, 2009

Separation of Concerns: The proxy pattern

The principle of Separation of Concerns is one of the main aspects of modern application frameworks like Spring or Hibernate. The intention is to separate the cross-cutting-concerns (e.g. database access, transaction management or security checks) from the implementation of the functional requirements.
One possible solution to realize a transparent separation of concerns is to use the proxy design pattern. A proxy is some kind of wrapper, which controls the access to the interface of any object. Therefore the proxy implements the same interface as the wrapped object. By using the proxy pattern you're able to extend or change the behavior of an object without changing the object itself.



It's quite simple to implement the proxy pattern in Java. The so called JDK proxies are part of the Java API since version 1.3. All you need is the Interface InvocationHandler and the helper class Proxy. Let's take a look at a simple example.
Given an interface:
public interface Service {
public void foobar();
}

There might be the following implementation of the interface for which you want to monitor the performance at runtime:
public class ServiceToBeMonitored implements Service {
@Override
public void foobar() {
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}

Instead of writing the performance-measuring-code directly into the service implementation we're separating this concern by using the proxy pattern. Therefor we implement the InvocationHandler interface:
public class PerformanceMonitor implements InvocationHandler {
private final Object proxiedInstance;

public PerformanceMonitor(Object proxiedInstance) {
this.proxiedInstance = proxiedInstance;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long t0 = System.nanoTime();
Object result = method.invoke(proxiedInstance, args);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println("Invocation of method " + method.getName() + "() took " + millis + " ms");
return result;
}
}

That's it. Now we're ready to create of proxy. The proxy delegates method calls to the wrapped object.
Service service = new ServiceToBeMonitored();
PerformanceMonitor handler = new PerformanceMonitor(service);
Service proxy = (Service) Proxy.newProxyInstance(
service.getClass().getClassLoader(),
new Class[]{ Service.class },
handler);

Calling proxy.foobar() results in:
Invocation of method foobar() took 201 ms  

4 comments:

Mahmoud Rabie said...

what happened behind the scene ?, how the interface was implemented on the fly ?

Benjamin said...

Hi Mahmoud,

internally the JDK creates a proxy-class at runtime which is capable of dynamicly implementing interfaces. This class dispatches method calls to it's invocation handlers using the Java Reflection API. The generation of this proxy-class is hidden in class sun.misc.ProxyGenerator (no source code available).

For further reading check out Suns tech guide: http://java.sun.com/javase/6/docs/technotes/guides/reflection/proxy.html

dharmendra said...

Great Explanation. Another great article i recommend is:

this

Ashok Kumar Jha said...

Good Example for SoC using proxy pattern.