English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spring AOP example

Gives Spring1.2Old-style AOP (Based on dtd) implementation example.

Although in Spring 3Supported, but the advice usage will be learned with Spring AOP and AspectJ on the next page.

spring1.2Old-style aop implementation supports4types of Advice.

Before AdviceIt executes before the actual method call. After AdviceIt executes after the actual method call. If the method returns a value, it executes after the return value. Around AdviceIt executes before and after the actual method call. Throws AdviceIf the actual method throws an exception, execute the Advice.

Note: To understand the basic concepts of Spring AOP, please visit the previous page.

Advice hierarchy

Let's understand the Advice hierarchy through the following chart:

All are interfaces in aop.

MethodBeforeAdvice interface extension of BeforeAdvice interface.

AfterReturningAdvice interface extension of AfterAdvice interface.

ThrowsAdvice interface extension AfterAdvice interface.

MethodInterceptor interface extension Interceptor interface. It is used around Advice.

1MethodBeforeAdvice example

Create a class that contains the actual business logic.

File: A.java

package com.w3codebox;
public class A {
public void m(){System.out.println("actual business logic");}
}

Now, create an advisor class that implements the MethodBeforeAdvice interface.

File: BeforeAdvisor.java

package com.w3codebox;
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 the xml file, create3Three beans, one for A class, the second for Advisor class, and the third for ProxyFactoryBean class.

File: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.BeforeAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

Understanding ProxyFactoryBean class:

ProxyFactoryBean provided by the Spring Framework. It includes2Two properties: target and interceptorNames. An instance of A class will be regarded as the target object, and an instance of Advisor class will be regarded as the interceptor. You need to pass the advisor object as a list object as shown in the above xml file.

The writing of ProxyFactoryBean class is as follows:

public class ProxyFactoryBean{
private Object target;
private List interceptorNames;
//getters and setters
}

Now, let's call the actual method.

File: Test.java

package com.w3codebox;
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

In MethodBeforeAdvice, we can print other information, such as method name, method parameters, target object, target object class name, proxy class, and so on.

You only need to change two classes, BeforeAdvisor.java and Test.java.

File: BeforeAdvisor.java

package com.w3codebox;
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");
		System.out.println("method info:");+method.getName()+" "+method.getModifiers());
		System.out.println("argument info:");
		for(Object arg:args)
			System.out.println(arg);
		System.out.println("target Object:");+target);
		System.out.println("target object class name: ");+target.getClass().getName());
	}
}

File: Test.java

package com.w3codebox;
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);
        System.out.println("proxy class name: ");+a.getClass().getName());
	a.m();
}
}

Output

proxy class name: com.w3codebox.A$EnhancerByCGLIB$409872b1
additional concern before actual logic
method info:m 1
argument info:
target Object:com.w3codebox.A@11dba45
target object class name: com.w3codebox.A
actual business logic

AfterReturningAdvice Example

Create a class that contains the actual business logic.

File: A.java

As the same as the previous example.

Now, create a consultant class that implements the AfterReturningAdvice interface.

File: AfterAdvisor.java

package com.w3codebox;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterAdvisor implements AfterReturningAdvice{
	@Override
	public void afterReturning(Object returnValue, Method method,
         Object[] args, Object target) throws Throwable {
		System.out.println("additional concern after returning advice");
	}
}

Create an XML file as shown in the previous example, you only need to change the advisor program class here.

File: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AfterAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

File: Test.java

As the same as the previous example.

Output

actual business logic
additional concern after returning advice

3)MethodInterceptor(AroundAdvice) example

Create a class that contains the actual business logic.

File: A.java

As the same as the previous example.

Now, create an advisor class that implements the MethodInterceptor interface.

File: AroundAdvisor.java

package com.w3codebox;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdvisor implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object obj;
		System.out.println("additional concern before actual logic");
		obj = mi.proceed();
		System.out.println("additional concern after actual logic");
		return obj;
	}
}

Create an XML file as shown in the previous example, you only need to change the advisor program class here.

File: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.A"></bean>
<bean id="ba" class="com.w3codebox.AroundAdvisor"></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

File: Test.java

As the same as the previous example.

Output

additional concern before actual logic
actual business logic
additional concern after actual logic

4Example of ThrowsAdvice

Create a class that contains the actual business logic.

File: Validator.java

package com.w3codebox;
public class Validator {
	public void validate(int age)throws Exception{
		if(age<18){
			throw new ArithmeticException("Not Valid Age");
		}
		else{
			System.out.println("vote confirmed");
		}
	}
}

Now, create a class that implements the ThrowsAdvice interface.

File: ThrowsAdvisor.java

package com.w3codebox;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsAdvisor implements ThrowsAdvice{
	public void afterThrowing(Exception ex){
		System.out.println("additional concern if exception occurs");
	}
}

Create an XML file as shown in the previous example. You only need to change the Validator class and Advisor class.

File: applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="obj" class="com.w3codebox.Validator"></bean>
<bean id="ba" class="com.w3codebox.ThrowsAdvisor></bean>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="obj"></property>
<property name="interceptorNames">
<list>
<value>ba</value>
</list>
</property>
</bean>
</beans>

File: Test.java

package com.w3codebox;
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);
	Validator v=factory.getBean("proxy",Validator.class);
	try{
	v.validate(12);
	}catch(Exception e){e.printStackTrace();}
}
}

Output

java.lang.ArithmeticException: Not Valid Age
additional concern if exception occurs
	at com.w3codebox.Validator.validate(Validator.java:7)
	at com.w3codebox.Validator$FastClassByCGLIB$562915cf.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invoke
Joinpoint(Cglib2AopProxy.java:692)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.
invoke(ThrowsAdviceInterceptor.java:124)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.
proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.
intercept(Cglib2AopProxy.java:625)
	at com.w3codebox.Validator$EnhancerByCGLIB$4230ed28.validate(<generated>)
	at com.w3codebox.Test.main(Test.java:15)