Pages Navigation Menu

Coding is much easier than you think

Spring AOP Concept using BeforeAdvice example

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
 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
    "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
 
<beans>
<!-- Bean Classes -->
    <bean id="beanTarget" class="com.simpleCodeStuff.aop.IteratorImpl" >
    <property name="flowName" value="existing code"/>
    </bean>
</beans> 

 

The existing output is

 
springAopExistingOutput
 

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

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
    "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
	<!-- Bean Classes -->
	<bean id="beanTarget" class="com.simpleCodeStuffs.aop.IteratorImpl">
		<property name="flowName" value="existing code" />
	</bean>

<!-- Bean configuration -->
   <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces">
			<value>com.simpleCodeStuffs.aop.Iterator</value>
		</property>
		<property name="target">
			<ref local="beanTarget" />
		</property>
		<property name="interceptorNames">
			<list>
				<value>theTracingBeforeAdvisor</value>
			</list>
		</property>
	</bean>



	<!-- Advisor pointcut definition for before advice -->
	<bean id="theTracingBeforeAdvisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice">
			<ref local="theTracingBeforeAdvice" />
		</property>
		<property name="pattern">
			<value>.*</value>
		</property>
	</bean>



<!-- Advice classes -->
     <bean id="theTracingBeforeAdvice" class="com.simpleCodeStuffs.aop.AopExampleBefore" />

</beans> 

 

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

 
springBeforeAdviceFinalOutput
 


 

About Mohaideen Jamil


Am currently working as a Struts 2 Developer in a reputed IT Organisations. I can help you with teaching Core java and Struts 2. Follow me on Facebook or Google Plus. If you like my tutorials, consider making a donation to this charity, thanks.