Sunday, 10 March 2013

Understanding Dynamic Proxy : Spring AOP Basics

Why AOP :

To Understand AOP(Aspect Oriented Programming), we need to understand Cross Cutting Concerns in software development . In every project , there is some amount of code which gets repeated in multiple classes , across several modules.For example logging which needs to be done for almost all classes and for all module.
This kind of code reduces code's re usability , maintainability and scalability.For example , if you want to take the class and reuse it somewhere else , where logging is not needed , you have to change this class . Similarly, if validation or logging is changed , we have to change almost each and every class wherever this is used .
A class should focus on it's core functionality , things like logging ,validation , transaction etc are not part of class functionality .
Aspect Oriented Programming is the paradigm to help us removing these cross cutting concerns. It provides us the tools and methodology to separate our cross cutting code from classes .

Proxy Pattern:

We can create a proxy of the object , which will take care of the cross cutting concern code.There are two kind of proxy patterns :
  • Static Proxy :

    Where we create a proxy object for every class. This is not feasible and practical
  • Dynamic Proxy :

    In this , proxies are created dynamically through reflection . This functionality is added from JDK 1.3 . dynamic Proxy form the basic building block of Spring AOP 
Here Class Example1 implements interface BasicFunc .
package com.somaniab.blog.ex;

public class Example1 implements Basicfunc{

 @Override
 public void method1() {
  System.out.println("executing method 1");  
 }
       
 
}
Here is the Interface Basicfunc
package com.somaniab.blog.ex;

public interface Basicfunc{

 public void method1();       
 
}
Now if we want to calculate execution time of method1 , we have to write that code in method itself , or we can create a proxy object. For creating proxy object , we create a Invocationhandler like this :
package com.somaniab.blog.ex;

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

public class MyInvocationHandler implements InvocationHandler{

 private Object target ;
  
        public MyInvocationHandler(Object target)
 {
  this.target = target;
 }
 
 
 public Object getTarget() {
  return target;
 }

 public void setTarget(Object target) {
  this.target = target;
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] params)
   throws Throwable {
  long a = System.currentTimeMillis();
  Object result =method.invoke(target ,params);
  System.out.println("total time taken  "+
                         (System.currentTimeMillis()-a));
  return result;
 }

}
In this invocation handler , we call the actual method as well as calculate the time taken.Now , in main class we create the proxy object by using Proxy class.
package com.somaniab.blog.ex;

import java.lang.reflect.Proxy;

public class MainClass {
      public static void main(String[] args) {
  
       Example1 ex = new Example1();
       
       Basicfunc proxied =(Basicfunc)Proxy
                           .newProxyInstance(MainClass.class.getClassLoader(),
         ex.getClass().getInterfaces() ,new MyInvocationHandler(ex));
       proxied.method1();
 }
}
For creating Proxy we pass classloader[mostly the same classloader as origin class],interfaces,and the invocationHandler (pass the original target object in the invocation handler ). The original class must implement a interface ,only those method declared in interface get proxied and then we cast the proxy to the interface type .

If you get Exception like this : java.lang.ClassCastException: $Proxy0 cannot be cast to com.somaniab.blog.ex.Example1 , it means your target class does not implement the interface.

In CGLib Proxy , there is no necessity of declaring interface.
So , this is how we made sure that our Example class write code for only method1 and we kept execution time calculation code out of it.

it is a very basic example , but it is the basic of Spring AOP.

Other frameworks implementing aop other than Spring AOP are AspectJ and JBOSS AOP

Don't forget to comment to make this article more usable :)