Spring AOP Concept using BeforeAdvice example
|
Take an example wherein there exists an interface ‘Iterator’. It is implemented by a class ‘IteratorImpl’(which obviously, overrides the methods of ‘Iterator’, in this case goNext() ). Consider a scenario wherein this set up is part of a very large code. Now, I get a requirement to insert a logging step into this code. This can be done using AOP with no impact at all on the existing classes.
** UPDATE: Spring Complete tutorial now available here.
Step 1 :
Include the required libraries in your classpath
Step 2 :
Creating the existing code set up as per our scenario
Create a new package. Click on your project SpringTutorial, select New->Package. Give com.simpleCodeStuff.aop. Create the interface Iterator with an abstract method(goNext() ) and a class IteratorImpl which implements Iterator(thus defining goNext() method).
File : Iterator.java
package com.simpleCodeStuffs.aop; public interface Iterator { void goNext(); }
File : IteratorImpl.java
package com.simpleCodeStuffs.aop; public class IteratorImpl implements Iterator{ String flowName; public void goNext() { System.out.println("goNext Method Called on flow - "+flowName); } public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } }
The call to the goNext() method is sent from a main class SpringAopMain, by loading the configuration metadata xml aopBeans.xml and consecutively loading the bean specified corresponding to IteratorImpl beanTarget(So far, AOP is not implemented. It is simple Spring IOC)
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context .getBean("beanTarget"); // Execute the public method of the bean IteratorInterface.goNext(); } }
The configuration metadata xml aopBeans.xml with the required bean definitions
File : aopBeans.xml
The existing output is
Step 3 :
In this step, let us take up the changes needed to insert the logging step, say before the goNext method is called.
Create a new class to perform the logging step -AopExampleBefore, which implements MethodBeforeAdvice class from the springframework. This class must hence define the abstract method before() from the implemented class.
File : AopExampleBefore.java
package com.simpleCodeStuffs.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class AopExampleBefore implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("Logging step :Before Advice Called"); } }
Now, majority of the changes are done in the xml which binds these classes using aop concept aopBeans.xml. Just as in the Spring IOC case, this configuration metadata xml has to be present directly under the src folder.
Note- our existing code undergoes no alteration which not only makes the changes easier but also leaves way for further changes in the code giving modularity to our code.
File : aopBeans.xml
com.simpleCodeStuffs.aop.Iterator
theTracingBeforeAdvisor .*
Explanation :
- target defines which bean is intercepted(or bypassed)
- interceptorNames Define which class (advice) you want to apply on this proxy /target object.
- proxyInterfaces provides the interface that has been implemented by the class referred by bean âtargetâ
- Advisor pointcut The bean that defines the ’advice’ and the ‘pattern’. As is clear from the terminology provided at the start of this concept, a pointcut has to match the joinpoint, so that a particular action is taken.
- Advice – the bean referring to the class which bypasses the ‘target’
- Pattern Specifies the pattern(characters)to look for in the method inside the ‘target’ class that has to be bypassed.
The only change in the existing code is the beanID which is called from the main method. Instead of directly calling for targetBean (class IteratorImpl), the bean taken up now will be businesslogicbean which provides the beans configuration.
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context .getBean("businesslogicbean"); // Execute the public method of the bean IteratorInterface.goNext(); } }
The output now is as follows
|