23 February 2010

Java Dynamic proxy

Java Dynamic proxies is amazing feature that enables you to add basic AOP-like (Aspect Oriented Programming) features to your own code easily.

I'll show you an example that will illustrate the idea more easily:

Suppose we have an interface “Calculator” that is defined as follows:
 package org.daz;  

public interface Calculator {
public int add (int x, int y);
public int subtract (int x, int y);
}

And here's an implementation for this interface:
 package org.daz;  

public class CalculatorImpl implements Calculator {

public int add(int x, int y) {
return x + y;
}

public int subtract(int x, int y) {
return x - y;
}
}

Because the logging is not a business concern, so we need to isolate it from the business code, so we need another place to place our logging code and then to apply this logging functionality to our business code with keeping the logging code a way from the business code, so lets create a Logging Proxy:

 package org.daz;  

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

public class LoggingProxy implements InvocationHandler {

private Object object;

public LoggingProxy(Object object) {
this.object = object;
}

public static Object newInstance(Object object) {
return Proxy.newProxyInstance(object.getClass()
.getClassLoader(), object.getClass()
.getInterfaces(), new LoggingProxy(object));
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
System.out.println("before method " + method.getName());
result = method.invoke(object, args);
System.out.println("after method " + method.getName());
return result;
}

}


And here's how we can use the logging (Aspect) with our business :
 package org.daz;  

public class Main {
public static void main(String[] args) {
Calculator calc = (Calculator) LoggingProxy.newInstance(new CalculatorImpl());
int result = calc.add(10, 20);
System.out.println(result);
}
}

And here's the output :
before method add
after method add
30

In the above example, we used a dynamic proxy to separate between a cross-cutting concern (Logging) from our business code.
Post a Comment