The following example illustrates creating a simple static pointcut in Spring AOP. As said in this post, a pointcut is a piece of code that decides for which methods the advice should be applied to.
A static pointcut is a type of point cut which filters methods on the basis of their name, the type of arguments, their class name etc but not by the values of the arguments passed to that method.
Theme of the application
The theme of the application is to illustrate a simple static pointcut. This pointcut defines that the advice should only be applied to a certain method. Here, that method isding()
.The
ding()
method contains a statement to print is a.The advice is an around advice i.e. some statements are executed before method invocation and some after method invocation. Now, the statement before calling
ding()
is Rama and the statement after calling ding()
is boy.Altogether print, Rama is a boy as output. This is a simple program that will better explain a simple static point cut.
Create a project in eclipse
- File -> New -> Project -> Java Project
- Give the project name spring39 and click Finish
- Now, the project is created.
- Under the Project Explorer (in the sidebar) you will see spring39. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
- Right click on the spring39 and click Properties
- On the left side, click on Java Build Path.
- Select the Libraries tab and then click on Add External Jars
- Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
- Click on OK and then you are read
To create a class
In the Project Explorer, navigate to spring39 and right click on spring39. Then go to New -> Class and give the name of the class as defined below.
Project structure
SimpleBean.java
This class contains the method ding() for which the advice will be applied. This is the target bean class.
package spring39;
public class SimpleBean {
public void ding()
{
System.out.print("is a");
}
public void dong()
{
System.out.println("is not");
}
}
SimpleAdvice.java - Around advice
This is the class that contains the advice code that will be applied.
package spring39;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
// A sample around advice
public class SimpleAdvice implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// Statement before method exeuction
System.out.print("Rama ");
// This method is used to proceed to next before/around advice (if any)
// otherwise, method is called simply
Object val=mi.proceed();
// Statement after method execution
System.out.print(" boy");
// Return the val, that indidates
// that the method is invoked successfully
// Next intercept will be proceeded if the val is returned
return val;
}
}
SimpleAdvice is the only advice defined in this example, so
mi.proceed()
invokes the method. Note that the invoke()
method is called only for those methods that satisfy the pointcut below.SimpleStaticPointcut.java
package spring39;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
// A point cut defines methods for which the advice should be applied to
public class SimpleStaticPointcut extends StaticMethodMatcherPointcut {
// Filters classes, this is executed first
@Override
public ClassFilter getClassFilter() {
return new ClassFilter(){
@Override
public boolean matches(Class<?> cls) {
// Only if the name of the class ends with SimpleBean
return cls.getName().endsWith("SimpleBean");
}
};
}
// After matching the class, now lets go to the
// methods in that class
@Override
public boolean matches(Method method, Class<?> cls) {
// Only if the method name equals ding
return (method.getName().equals("ding"));
}
}
Here, first the class on whose object the method is called, is filtered. So
getClassFilter()
is first called. If the ClassFilter
code decides to execute the method on that class. Then the matches()
method is executed.
The
matches()
method is executed once for every method no matter how many times it is called. When the matches()
is executed for a method, its value is cached i.e. whether that method is as specified in the matches()
.
Here, the code returns that only method with name ding() is allowed. Therefore, the
invoke()
method in the advice class is called only when ding()
is called. So the advice is applied only for ding() but not for dong()
.
Now,
ding()
matches the pointcut, so its value is true. Next, dong()
doesn't match the pointcut, so matches()
will return false for dong()
. Both these values are cached.
First,
matches()
method is called on all the methods when you call getProxy()
method. Next, again it is called when you call those methods the first time only. After, that no matter how many times you call those methods, matches()
will not be called.SpringPrg.java - Main class
package spring39;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
public class SpringPrg {
public static void main(String args[])
{
// Create target bean object
SimpleBean sb=new SimpleBean();
// Create a point cut that is static
// a point cut defines which method(s) on
// the target object should the advice be
// applied to
Pointcut p=new SimpleStaticPointcut();
// An advice is the code that is a cross-cutting
// concern
Advice advice=new SimpleAdvice();
// An advisor is a combination of advice and point cut
// i.e. it defines to whom the advice should be given
// and also the advice to be given
Advisor advisor=new DefaultPointcutAdvisor(p,advice);
// Create a ProxyFactory object
ProxyFactory pf=new ProxyFactory();
// Add the advisor
// With this you are adding both the advice
// and to which methods that should be applied
pf.addAdvisor(advisor);
// Set the target object
pf.setTarget(sb);
// Get the bean that is wrapped with advice
SimpleBean bean=(SimpleBean)pf.getProxy();
// call the proxied methods
bean.ding();
// a new line to separate both lines
System.out.println();
// call dong (advice will not be applied
// to this method) as defined in the point cut
bean.dong();
}
}
Output
Rama is a boy
is not
Also see before advice and after advice
No comments:
Post a Comment