Monday, August 8, 2016

Spring AOP Tutorial

What is AOP?
AOP is an acronym for Aspect Oriented Programming. It is a methodology that divides the program logic into pieces or parts or concerns.
It increases the modularity and the key unit is Aspect

AOP breaks the program logic into distinct parts (called concerns). It is used to increase modularity by cross-cutting concerns.

cross-cutting concern is a concern that can affect the whole application and should be centralized in one location in code as possible, such as transaction management, authentication, logging, security etc.

What are the advantages of spring AOP?
AOP enables you to dynamically add or remove concern before or after the business logic. It is pluggable and easy to maintain.

Why use AOP?
It provides the pluggable way to dynamically add the additional concern before, after or around the actual logic. Suppose there are 10 methods in a class as given below:
class A{  
public void m1(){...}  
public void m2(){...}  
public void m3(){...}  
public void m4(){...}  
public void m5(){...}  
public void n1(){...}  
public void n2(){...}  
public void p1(){...}  
public void p2(){...}  
public void p3(){...}  
}  

There are 5 methods that starts from m, 2 methods that starts from n and 3 methods that starts from p.
Understanding Scenario I have to maintain log and send notification after calling methods that starts from m.
Problem without AOP We can call methods (that maintains log and sends notification) from the methods starting with m. In such scenario, we need to write the code in all the 5 methods.
But, if client says in future, I don't have to send notification, you need to change all the methods. It leads to the maintenance problem.
Solution with AOP We don't have to call methods from the method. Now we can define the additional concern like maintaining log, sending notification etc. in the method of a class. Its entry is given in the xml file.
In future, if client says to remove the notifier functionality, we need to change only in the xml file. So, maintenance is easy in AOP.


Where use AOP?
AOP is mostly used in following cases:
  • to provide declarative enterprise services such as declarative transaction management.
  • It allows users to implement custom aspects.

What are the AOP terminology?
AOP terminologies or concepts are as follows:
  • JoinPoint
  • Advice
  • Pointcut
  • Aspect
  • Introduction
  • Target Object
  • Interceptor
  • AOP Proxy
  • Weaving

Join point
Join point is any point in your program such as method execution, exception handling, field access etc. Spring supports only method execution join point.

Advice
Advice represents an action taken by an aspect at a particular join point. There are different types of advices:
  • Before Advice: it executes before a join point.
  • After Returning Advice: it executes after a joint point completes normally.
  • After Throwing Advice: it executes if method exits by throwing an exception.
  • After (finally) Advice: it executes after a join point regardless of join point exit whether normally or exceptional return.
  • Around Advice: It executes before and after a join point.

Pointcut
It is an expression language of AOP that matches join points.

Introduction
It means introduction of additional method and fields for a type. It allows you to introduce new interface to any advised object.

Target Object
It is the object i.e. being advised by one or more aspects. It is also known as proxied object in spring because Spring AOP is implemented using runtime proxies.

Aspect
It is a class that contains advices, joinpoints etc.

Interceptor
It is an aspect that contains only one advice.

AOP Proxy
It is used to implement aspect contracts, created by AOP framework. It will be a JDK dynamic proxy or CGLIB proxy in spring framework.

Weaving
It is the process of linking aspect with other application types or objects to create an advised object. Weaving can be done at compile time, load time or runtime. Spring AOP performs weaving at runtime.

AOP Implementations
AOP implementations are provided by:
  1. AspectJ
  2. Spring AOP
  3. JBoss AOP

Spring AOP Example
There are given examples of Spring1.2 old style AOP (dtd based) implementation.
Though it is supported in spring 3, but it is recommended to use spring aop with aspectJ that we are going to learn in next page.
There are 4 types of advices supported in spring1.2 old style aop implementation.
  1. Before Advice it is executed before the actual method call.
  2. After Advice it is executed after the actual method call. If method returns a value, it is executed after returning value.
  3. Around Advice it is executed before and after the actual method call.
  4. Throws Advice it is executed if actual method throws exception.
To understand the basic concepts of Spring AOP, visit the previous page.

Understanding the hierarchy of advice interfaces
Let's understand the advice hierarchy by the diagram given below:

All are interfaces in aop.
MethodBeforeAdvice interface extends the BeforeAdvice interface.
AfterReturningAdvice interface extends the AfterAdvice interface.
ThrowsAdvice interface extends the AfterAdvice interface.
MethodInterceptor interface extends the Interceptor interface. It is used in around advice.

MethodBeforeAdvice Example
Create a class that contains actual business logic.
File: A.java
public class A {  
public void m(){System.out.println("actual business logic");}  
}  
Now, create the advisor class that implements MethodBeforeAdvice interface.

File: BeforeAdvisor.java
import java.lang.reflect.Method;  
import org.springframework.aop.MethodBeforeAdvice;  
public class BeforeAdvisor implements MethodBeforeAdvice{  
   @Override  
    public void before(Method method, Object[] args, Object target)throws Throwable {  
        System.out.println("additional concern before actual logic");  
    }  
}  
In xml file, create 3 beans, one for A class, second for Advisor class and third for ProxyFactoryBeanclass.
File: applicationContext.xml
  
  
  
Understanding ProxyFactoryBean class:
The ProxyFactoryBean class is provided by Spring Famework. It contains 2 properties target and interceptorNames. The instance of A class will be considered as target object and the instance of advisor class as interceptor. You need to pass the advisor object as the list object as in the xml file given above.
The ProxyFactoryBean class is written something like this:
public class ProxyFactoryBean{  
private Object target;  
private List interceptorNames;  
//getters and setters  
}  
Now, let's call the actual method.
File: Test.java
import org.springframework.beans.factory.BeanFactory;  
import org.springframework.beans.factory.xml.XmlBeanFactory;  
import org.springframework.core.io.ClassPathResource;  
import org.springframework.core.io.Resource;  
public class Test {  
public static void main(String[] args) {  
    Resource r=new ClassPathResource("applicationContext.xml");  
    BeanFactory factory=new XmlBeanFactory(r);  
      
    A a=factory.getBean("proxy",A.class);  
    a.m();  
}  
}  
Output
  1. additional concern before actual logic  
  2. actual business logic  
Spring AOP AspectJ Annotation Example
The Spring Framework recommends you to use Spring AspectJ AOP implementation over the Spring 1.2 old style dtd based AOP implementation because it provides you more control and it is easy to use.
There are two ways to use Spring AOP AspectJ implementation:
  1. By annotation: We are going to learn it here.
  2. By xml configuration (schema based): We will learn it in next page.
Spring AspectJ AOP implementation provides many annotations:
  1. @Aspect declares the class as aspect.
  2. @Pointcut declares the pointcut expression.

The annotations used to create advices are given below:
  1. @Before declares the before advice. It is applied before calling the actual method.
  2. @After declares the after advice. It is applied after calling the actual method and before returning result.
  3. @AfterReturning declares the after returning advice. It is applied after calling the actual method and before returning result. But you can get the result value in the advice.
  4. @Around declares the around advice. It is applied before and after calling the actual method.
  5. @AfterThrowing declares the throws advice. It is applied if actual method throws exception.

Understanding Pointcut
Pointcut is an expression language of Spring AOP.
The @Pointcut annotation is used to define the pointcut. We can refer the pointcut expression by name also. Let's see the simple example of pointcut expression.
@Pointcut("execution(* Operation.*(..))")  
private void doSomething() {}  
The name of the pointcut expression is doSomething(). It will be applied on all the methods of Operation class regardless of return type.

Understanding Pointcut Expressions
Let's try the understand the pointcut expressions by the examples given below:
@Pointcut("execution(public * *(..))")  
It will be applied on all the public methods.

@Pointcut("execution(public Operation.*(..))")  
It will be applied on all the public methods of Operation class.

@Pointcut("execution(* Operation.*(..))")  
It will be applied on all the methods of Operation class.

@Pointcut("execution(public Employee.set*(..))")  
It will be applied on all the public setter methods of Employee class.

@Pointcut("execution(int Operation.*(..))")  
It will be applied on all the methods of Operation class that returns int value.

1) @Before Example
The AspectJ Before Advice is applied before the actual business logic method. You can perform any operation here such as conversion, authentication etc.
Create a class that contains actual business logic.
File: Operation.java
   public  class Operation{  
   public void msg(){System.out.println("msg method invoked");}  
    public int m(){System.out.println("m method invoked");return 2;}  
    public int k(){System.out.println("k method invoked");return 3;}  
}  
Now, create the aspect class that contains before advice.
File: TrackOperation.java
  
@Aspect  
public class TrackOperation{  
    @Pointcut("execution(* Operation.*(..))")  
    public void k(){}//pointcut name  
      
    @Before("k()")//applying pointcut on before advice  
    public void myadvice(JoinPoint jp)//it is advice (before advice)  
    {  
        System.out.println("additional concern");  
        //System.out.println("Method Signature: "  + jp.getSignature());  
   }  
}  
Now create the applicationContext.xml file that defines beans.
File: applicationContext.xml
  
  

Now, let's call the actual method.
File: Test.java
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        Operation e = (Operation) context.getBean("opBean");  
        System.out.println("calling msg...");  
        e.msg();  
        System.out.println("calling m...");  
        e.m();  
        System.out.println("calling k...");  
        e.k();  
    }  
}  
Output
  1. calling msg...  
  2. additional concern  
  3. msg() method invoked  
  4. calling m...  
  5. additional concern  
  6. m() method invoked  
  7. calling k...  
  8. additional concern  
  9. k() method invoked  
As you can see, additional concern is printed before msg(), m() and k() method is invoked.
Now if you change the pointcut expression as given below:
  1. @Pointcut("execution(* Operation.m*(..))")  
Now additional concern will be applied for the methods starting with m in Operation class. Output will be as this:
  1. calling msg...  
  2. additional concern  
  3. msg() method invoked  
  4. calling m...  
  5. additional concern  
  6. m() method invoked  
  7. calling k...  
  8. k() method invoked  
Now you can see additional concern is not printed before k() method invoked.

Spring AOP AspectJ Xml Configuration Example
Spring enables you to define the aspects, advices and pointcuts in xml file.
In the previous page, we have seen the aop examples using annotations. Now we are going to see same examples by the xml configuration file.
Let's see the xml elements that are used to define advice.
  1. aop:before It is applied before calling the actual business logic method.
  2. aop:after It is applied after calling the actual business logic method.
  3. aop:after-returning it is applied after calling the actual business logic method. It can be used to intercept the return value in advice.
  4. aop:around It is applied before and after calling the actual business logic method.
  5. aop:after-throwing It is applied if actual business logic method throws exception.

1) aop:before Example
The AspectJ Before Advice is applied before the actual business logic method. You can perform any operation here such as conversion, authentication etc.
Create a class that contains actual business logic.
File: Operation.java
public  class Operation{  
    public void msg(){System.out.println("msg method invoked");}  
    public int m(){System.out.println("m method invoked");return 2;}  
    public int k(){System.out.println("k method invoked");return 3;}  
}  
Now, create the aspect class that contains before advice.
File: TrackOperation.java
import org.aspectj.lang.JoinPoint;  
public class TrackOperation{  
    public void myadvice(JoinPoint jp)//it is advice  
    {  
        System.out.println("additional concern");  
        //System.out.println("Method Signature: "  + jp.getSignature());  
    }  
}  
Now create the applicationContext.xml file that defines beans.
File: applicationContext.xml
  
      
  
Now, let's call the actual method.
File: Test.java
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        Operation e = (Operation) context.getBean("opBean");  
        System.out.println("calling msg...");  
        e.msg();  
        System.out.println("calling m...");  
        e.m();  
        System.out.println("calling k...");  
        e.k();  
    }  
}  
Output
  1. calling msg...  
  2. additional concern  
  3. msg() method invoked  
  4. calling m...  
  5. additional concern  
  6. m() method invoked  
  7. calling k...  
  8. additional concern  
  9. k() method invoked  
As you can see, additional concern is printed before msg(), m() and k() method is invoked.



No comments:

Post a Comment