Spring AOP “BeforeAdvice, AfterReturningAdvice

Considering a log has to be printed once the method execution(in this case, after value is returned from method) in the ‘target’ bean is complete, then AfterReturningAdvice can be made use of. To insert this functionality into our existing code, let us expand the existing scenario and take that another method(goPrevious() ) is present in the existing interface -Iterator and subsequently defined in IteratorImpl class.
The design needs to be modified in such a way that a log is printed before execution of the goNext() method (as already available) and after execution of the goPrevious() method.

** UPDATE: Spring Complete tutorial now available here.

Step 1 :

Add another method declaration in Interface Iterator and correspondingly provide the method definition in IteratorImpl class.

File : Iterator.java

package com.simpleCodeStuffs.aop;

        public interface Iterator {
                void goPrevious();
            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 void goPrevious(){
     System.out.println("goPrevious Method called on flow - "+flowName);
    }
    
        public String getFlowName() {
                return flowName;
        }
        public void setFlowName(String flowName) {
                this.flowName = flowName;
        }
}

Step 2 :


Create a new class AopExampleAfter to provide the newly added functionality of logging after returning from the method goPrevious(). The concept underlying is much the same as seen in the previous tutorial for Before Advice.

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");
}
}

File : AopExampleAfter.java
package com.simpleCodeStuffs.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AopExampleAfter implements AfterReturningAdvice{
        @Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
                        Object arg3) throws Throwable {
 System.out.println("Logging step : 
  After returning advice called on "+arg0);
}
}

AopExampleAfter is similar to implementing and defining of the abstract method from the supporting class done in the previous example of MethodBeforeAdvice.

Step 3 :

The main changes need to be done at the aopBeans.xml.

In the available ‘businesslogicbean’ bean, add another value in the list of €œinterceptorNames€. Similar to the logic in previous tutorial, define advisor(with advice and pattern as properties) bean and advice bean. In case Before Advice€™ logic is not needed,
remove <value>theTracingBeforeAdvisor</value> from the list and its associated 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>
    
      <!- Bean configuration
    <bean id="businesslogicbean"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>com.simpleCodeStuff.aop.Iterator</value>
        </property>
        <property name="target">
            <ref local="beanTarget" />
        </property>
        <property name="interceptorNames">
            <list>
                <value>theTracingBeforeAdvisor</value>
                <value>theTracingAfterAdvisor</value>
            </list>
        </property>
    </bean>
    
    <bean id="theTracingAfterAdvisor"
   class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="advice">
         <ref local="theTracingAfterAdvice "/>
      </property>
      <property name="pattern">
         <value>.*Previous*.</value>
      </property>
   </bean>
    <bean id="theTracingAfterAdvice"
      class="com.simpleCodeStuff.aop.AopExampleAfter"/>

   
 
    
 
    <!- 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>.*Next*.</value>
        </property>
    </bean>
 
   
 
    <!- Advice classes
    <bean id="theTracingBeforeAdvice"
        class="com.simpleCodeStuff.aop.AopExampleBefore" />
    
 </beans> 

Here, note that log has to be printed BEFORE method execution in the case of goNext() method and AFTER method execution in the case of goPrevious() method.
Accordingly, the value in “pattern” in the corresponding Advisor bean is modified.

Step 4 :

Make a call to the newly added goPrevious() method as well, from the Main class.

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();
        IteratorInterface.goPrevious();
    }
} 

Step 6 :

Lets make a small change in the aopBeans.xml to understand the usage of ‘pattern’ in the advisor bean. When no explicit value of pattern is mentioned for the two advisors(before,after),
then a log is printed before and after the execution of both methods.

File : aopBeans.xml
 <bean id="theTracingAfterAdvisor"
   class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="advice">
         <ref local="theTracingAfterAdvice"/>
      </property>
      <property name="pattern">
         <value>.*</value>
      </property>
   </bean>
    <bean id="theTracingAfterAdvice"
      class="com.simpleCodeStuff.aop.AopExampleAfter"/>

   
 
    
 
    <!- 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>