Main Tutorials

Spring AOP Example – Pointcut , Advisor

In last Spring AOP advice examples, the entire methods of a class are intercepted automatically. But for most cases, you may just need a way to intercept only one or two methods, this is what ‘Pointcut’ come for. It allow you to intercept a method by it’s method name. In addition, a ‘Pointcut’ must be associated with an ‘Advisor’.

In Spring AOP, comes with three very technical terms – Advices, Pointcut , Advisor, put it in unofficial way…

  • Advice – Indicate the action to take either before or after the method execution.
  • Pointcut – Indicate which method should be intercept, by method name or regular expression pattern.
  • Advisor – Group ‘Advice’ and ‘Pointcut’ into a single unit, and pass it to a proxy factory object.

Review last Spring AOP advice examples again.

File : CustomerService.java


package com.mkyong.customer.services;

public class CustomerService
{
	private String name;
	private String url;

	public void setName(String name) {
		this.name = name;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public void printName(){
		System.out.println("Customer name : " + this.name);
	}
	
	public void printURL(){
		System.out.println("Customer website : " + this.url);
	}
	
	public void printThrowException(){
		throw new IllegalArgumentException();
	}
	
}

File : Spring-Customer.xml


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="customerService" class="com.mkyong.customer.services.CustomerService">
		<property name="name" value="Yong Mook Kim" />
		<property name="url" value="https://mkyong.com" />
	</bean>

	<bean id="hijackAroundMethodBeanAdvice" class="com.mkyong.aop.HijackAroundMethod" />

	<bean id="customerServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

		<property name="target" ref="customerService" />

		<property name="interceptorNames">
			<list>
				<value>hijackAroundMethodBeanAdvice</value>
			</list>
		</property>
	</bean>
</beans>

File : HijackAroundMethod.java


package com.mkyong.aop;

import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class HijackAroundMethod implements MethodInterceptor {
	@Override
	public Object invoke(MethodInvocation methodInvocation) throws Throwable {

		System.out.println("Method name : "
				+ methodInvocation.getMethod().getName());
		System.out.println("Method arguments : "
				+ Arrays.toString(methodInvocation.getArguments()));

		System.out.println("HijackAroundMethod : Before method hijacked!");

		try {
			Object result = methodInvocation.proceed();
			System.out.println("HijackAroundMethod : Before after hijacked!");

			return result;

		} catch (IllegalArgumentException e) {

			System.out.println("HijackAroundMethod : Throw exception hijacked!");
			throw e;
		}
	}
}

Run it


package com.mkyong.common;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mkyong.customer.services.CustomerService;

public class App {
	public static void main(String[] args) {
		ApplicationContext appContext = new ClassPathXmlApplicationContext(
				new String[] { "Spring-Customer.xml" });

		CustomerService cust = (CustomerService) appContext
				.getBean("customerServiceProxy");

		System.out.println("*************************");
		cust.printName();
		System.out.println("*************************");
		cust.printURL();
		System.out.println("*************************");
		try {
			cust.printThrowException();
		} catch (Exception e) {
		}
	}
}

Output


*************************
Method name : printName
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer name : Yong Mook Kim
HijackAroundMethod : Before after hijacked!
*************************
Method name : printURL
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer website : https://mkyong.com
HijackAroundMethod : Before after hijacked!
*************************
Method name : printThrowException
Method arguments : []
HijackAroundMethod : Before method hijacked!
HijackAroundMethod : Throw exception hijacked!

The entire methods of customer service class are intercepted. Later, we show you how to use “pointcuts” to intercept only printName() method.

Pointcuts example

You can match the method via following two ways :

  1. Name match
  2. Regular repression match

1. Pointcuts – Name match example

Intercept a printName() method via ‘pointcut’ and ‘advisor’. Create a NameMatchMethodPointcut pointcut bean, and put the method name you want to intercept in the ‘mappedName‘ property value.


	<bean id="customerPointcut"
        class="org.springframework.aop.support.NameMatchMethodPointcut">
		<property name="mappedName" value="printName" />
	</bean>

Create a DefaultPointcutAdvisor advisor bean, and associate both advice and pointcut.


	<bean id="customerAdvisor"
		class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut" ref="customerPointcut" />
		<property name="advice" ref="hijackAroundMethodBeanAdvice" />
	</bean>

Replace the proxy’s ‘interceptorNames’ to ‘customerAdvisor’ (it was ‘hijackAroundMethodBeanAdvice’).


	<bean id="customerServiceProxy"
		class="org.springframework.aop.framework.ProxyFactoryBean">

		<property name="target" ref="customerService" />
		
		<property name="interceptorNames">
			<list>
				<value>customerAdvisor</value>
			</list>
		</property>
	</bean>

Full bean configuration file


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="customerService" class="com.mkyong.customer.services.CustomerService">
		<property name="name" value="Yong Mook Kim" />
		<property name="url" value="https://mkyong.com" />
	</bean>

	<bean id="hijackAroundMethodBeanAdvice" class="com.mkyong.aop.HijackAroundMethod" />

	<bean id="customerServiceProxy" 
                class="org.springframework.aop.framework.ProxyFactoryBean">

		<property name="target" ref="customerService" />

		<property name="interceptorNames">
			<list>
				<value>customerAdvisor</value>
			</list>
		</property>
	</bean>

	<bean id="customerPointcut" 
                class="org.springframework.aop.support.NameMatchMethodPointcut">
		<property name="mappedName" value="printName" />
	</bean>

	<bean id="customerAdvisor" 
                 class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut" ref="customerPointcut" />
		<property name="advice" ref="hijackAroundMethodBeanAdvice" />
	</bean>

</beans>

Run it again, output


*************************
Method name : printName
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer name : Yong Mook Kim
HijackAroundMethod : Before after hijacked!
*************************
Customer website : https://mkyong.com
*************************

Now, you only intercept the printName() method.

PointcutAdvisor
Spring comes with PointcutAdvisor class to save your work to declare advisor and pointcut into different beans, you can use NameMatchMethodPointcutAdvisor to combine both into a single bean.


	<bean id="customerAdvisor"
		class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
	
		<property name="mappedName" value="printName" />
		<property name="advice" ref="hijackAroundMethodBeanAdvice" />
	
	</bean>

2. Pointcut – Regular expression example

You can also match the method’s name by using regular expression pointcut – RegexpMethodPointcutAdvisor.


	<bean id="customerAdvisor"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="patterns">
			<list>
				<value>.*URL.*</value>
			</list>
		</property>

		<property name="advice" ref="hijackAroundMethodBeanAdvice" />
	</bean>

Now, it intercepts the method which has words ‘URL’ within the method name. In practice, you can use it to manage DAO layer, where you can declare “.*DAO.*” to intercept all your DAO classes to support transaction.

Download Source Code

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
39 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
SivaKarthik
11 years ago

was tried a lot to unederstand aop concepts.. read few articles nd books.. but not got clear idea abt whats the purpose of aop..
after reading this tutorial, now i got clear idea.. its clearly explained… thank you.

Mateen Mansoori
2 years ago

I went through almost 15-20 article before reading this but those tutorials were not this much simple, Finally got some simple and awesome tutorial to understand the AOP concept, Thanks.

kumar
5 years ago

how could i achieve, if i want to have a pattern for matching particular method argument using org.springframework.aop.support.RegexpMethodPointcutAdvisor ?

Dmitry
7 years ago

Nice! but if I run CustomerService (implements Runnable) in another thread (like:
Thread customerServiceThread = new Thread(customerService);
customerServiceThread.start(); )
I get result only of method run().

Kalaivani
9 years ago

which are the required jars for Spring AOP?

sasi
9 years ago

+thanx

shirish kulkarni
9 years ago

how do we configure these point cuts for xml free spring….. basically i am looking to integrate this performancemonitorinterceptor

Harikrishna Kollipara
10 years ago

hi mkong it is very nice what you are present blog …learned alot from this blog

Ashish
10 years ago

I always seek out your blog to understand something new! Keep writing! 🙂

JPJR
10 years ago

nice job – thank you.

reetesh
10 years ago

Awesome..very good explaination

Brad
10 years ago

Thanks for the valuable tutorial! Does this style of Spring AoP framework support the interception of calls with specific parameters and return values? For example, if printName was declared like:

public String printName(String param1, String param2){}

Brad
10 years ago
Reply to  Brad

And more importantly for my circumstances, could we intercept a class that was not a bean? For example, if the CustomerService class was a non-bean java class, could we reference and intercept one of its methods?

Ali
10 years ago

Excelent tutorial,

sridhar
10 years ago

Very nice and informative… its helping me in many situation

Ayodeji
10 years ago

Thanks for your continuous help mykong

Divya
11 years ago

Its very clear…

var
11 years ago

awesome nice explanation 🙂

Basavaraj
11 years ago

Good article..!

Basavaraj
11 years ago

Good article..!Easy to grasp the basics..!

Prashant Bhagwani
11 years ago

Great Work !!

Thanks alot

subash961
11 years ago

really good tutorial..

Gopal Nayk
11 years ago

find solution to this sight.

lakshmi
11 years ago

Awesome. Your explanation is very good and easy to understand. Thanks for it.

venkat
11 years ago

cau you please explain callback methods in hibernate.

shankar
11 years ago

great tutorial…now I can understand spring aop.

thanks a lot !!

Wojtek
11 years ago

“put it in unofficial way” – I wish everybody writing tutorials concentrated on simplicity, even at the cost of putting something in an unofficial way. Those one-line explanations of these terms really appeal to me 🙂

Fahim
11 years ago
Reply to  mkyong

Simply awesome explanation. I read a whole book chapter on the same subject, but this one page explanation is far more better than that.

Gopal Nayk
11 years ago
Reply to  mkyong

Your explanation is very good and easy to understand I facing many problem in spring.

Ajay
11 years ago

Very helpfull

Beniton
11 years ago

Super

Prashant
12 years ago

Great work! awesome

tumit
12 years ago

Very nice tutorial