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.
A 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:
- AspectJ
- Spring AOP
- 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.
- Before Advice it
is executed before the actual method call.
- After Advice it
is executed after the actual method call. If method returns a value, it is
executed after returning value.
- Around Advice it
is executed before and after the actual method call.
- 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
- additional concern before actual logic
- 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:
- By annotation: We
are going to learn it here.
- By xml configuration
(schema based): We will learn it in next page.
Spring
AspectJ AOP implementation provides many annotations:
- @Aspect declares
the class as aspect.
- @Pointcut declares
the pointcut expression.
The
annotations used to create advices are given below:
- @Before declares
the before advice. It is applied before calling the actual method.
- @After declares
the after advice. It is applied after calling the actual method and before
returning result.
- @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.
- @Around declares
the around advice. It is applied before and after calling the actual method.
- @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
- calling msg...
- additional concern
- msg() method invoked
- calling m...
- additional concern
- m() method invoked
- calling k...
- additional concern
- 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:
- @Pointcut("execution(* Operation.m*(..))")
Now
additional concern will be applied for the methods starting with m in Operation
class. Output will be as this:
- calling msg...
- additional concern
- msg() method invoked
- calling m...
- additional concern
- m() method invoked
- calling k...
- 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.
- aop:before It
is applied before calling the actual business logic method.
- aop:after It
is applied after calling the actual business logic method.
- aop:after-returning it
is applied after calling the actual business logic method. It can be used
to intercept the return value in advice.
- aop:around It
is applied before and after calling the actual business logic method.
- 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
- calling msg...
- additional concern
- msg() method invoked
- calling m...
- additional concern
- m() method invoked
- calling k...
- additional concern
- k() method invoked
As
you can see, additional concern is printed before msg(), m() and k() method is
invoked.
No comments:
Post a Comment