Let’s first to see the three very technical terms as below.
Adivce - 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
No pointcut example MyLogicClass 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package spring.test.aop;public class MyLogicClass { public void logicMethodOne () { System.out.println("This is from logicMethodOne" ); } public void logicMethodTwo () { System.out.println("This is from logicMethodTwo" ); } public void testLogic () { System.out.println("This is from testLogic" ); } }
MyAroundAdvice.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package spring.test.aop;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class MyAroundAdvice implements MethodInterceptor { @Override public Object invoke (MethodInvocation invocation) throws Throwable { System.out.println("Before method execuation" ); Object result = invocation.proceed(); System.out.println("After method execuation" ); return result; } }
App.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package spring.test.aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class App { private static ApplicationContext applicationContext; public static void main (String[] args) { applicationContext = new ClassPathXmlApplicationContext ("springConfig.xml" ); MyLogicClass logicClass = (MyLogicClass)applicationContext.getBean("proxyFactoryBean" ); System.out.println("\n--------------------\n" ); logicClass.logicMethodOne(); System.out.println("\n--------------------\n" ); logicClass.logicMethodTwo(); System.out.println("\n--------------------\n" ); logicClass.testLogic(); System.out.println("\n--------------------\n" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" > <beans > <bean id ="myAroundAdvice" class ="spring.test.aop.MyAroundAdvice" /> <bean id ="myLogicClass" class ="spring.test.aop.MyLogicClass" /> <bean id ="proxyFactoryBean" class ="org.springframework.aop.framework.ProxyFactoryBean" > <property name ="interceptorNames" > <list > <value > myAroundAdvice</value > </list > </property > <property name ="target" ref ="myLogicClass" /> </bean > </beans >
output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 -------------------- Before method execuation This is from logicMethodOne After method execuation -------------------- Before method execuation This is from logicMethodTwo After method execuation -------------------- Before method execuation This is from testLogic After method execuation --------------------
In above example, all logic methods of the class has been intercepted due to the application doesn’t use the pointcut to specific.
Name match example And now, we just want to intercept the method testLogic , so we need to create NameMatchMethodPointcut bean in spring config xml. and put the method name you want to intercept to the mappedName property value.
1 2 3 <bean id ="nameMatchPointcut" class ="org.springframework.aop.support.NameMatchMethodPointcut" > <property name ="mappedName" value ="testLogic" /> </bean >
And also you can mapped multiple methods with mappedNames , like below.
1 2 3 4 5 6 7 8 <bean id ="nameMatchPointcut" class ="org.springframework.aop.support.NameMatchMethodPointcut" > <property name ="mappedNames" > <list > <value > logicMethodOne</value > <value > logicMethodTwo</value > </list > </property > </bean >
Then create DefaultPointcutAdvisor bean to group and associate the pointcut and advice.
1 2 3 4 <bean id ="myPointcutAdvisor" class ="org.springframework.aop.support.DefaultPointcutAdvisor" > <property name ="pointcut" ref ="nameMatchPointcut" /> <property name ="advice" ref ="myAroundAdvice" /> </bean >
Replace the interceptorNames of ProxyFactoryBean with the new Advisor.
1 2 3 4 5 6 7 8 <bean id ="proxyFactoryBean" class ="org.springframework.aop.framework.ProxyFactoryBean" > <property name ="interceptorNames" > <list > <value > myPointcutAdvisor</value > </list > </property > <property name ="target" ref ="myLogicClass" /> </bean >
It’s done, let’s see the full spring config file and output.
springConfig.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd" > <beans > <bean id ="myAroundAdvice" class ="spring.test.aop.MyAroundAdvice" /> <bean id ="myLogicClass" class ="spring.test.aop.MyLogicClass" /> <bean id ="nameMatchPointcut" class ="org.springframework.aop.support.NameMatchMethodPointcut" > <property name ="mappedName" value ="testLogic" /> </bean > <bean id ="myPointcutAdvisor" class ="org.springframework.aop.support.DefaultPointcutAdvisor" > <property name ="pointcut" ref ="nameMatchPointcut" /> <property name ="advice" ref ="myAroundAdvice" /> </bean > <bean id ="proxyFactoryBean" class ="org.springframework.aop.framework.ProxyFactoryBean" > <property name ="interceptorNames" > <list > <value > myPointcutAdvisor</value > </list > </property > <property name ="target" ref ="myLogicClass" /> </bean > </beans >
output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -------------------- This is from logicMethodOne -------------------- This is from logicMethodTwo -------------------- Before method execuation This is from testLogic After method execuation --------------------
Regular expression example Also we can use regular expression to match methods which should be intercepted. Create RegexpMethodPointcutAdvisor bean and set the pattern property value with regular expression and combine with advice.
1 2 3 4 5 <bean id ="regexPointcutAdvisor" class ="org.springframework.aop.support.RegexpMethodPointcutAdvisor" > <property name ="pattern" value =".*Method.*" /> <property name ="advice" ref ="myAroundAdvice" /> </bean >
And you can specific multiple patterns with patterns property.
1 2 3 4 5 6 7 8 9 <bean id ="regexPointcutAdvisor" class ="org.springframework.aop.support.RegexpMethodPointcutAdvisor" > <property name ="patterns" > <list > <value > .*Method.*</value > </list > </property > <property name ="advice" ref ="myAroundAdvice" /> </bean >
Finally pass the advisor to the ProxyFactoryBean .
1 2 3 4 5 6 7 8 <bean id ="proxyFactoryBean" class ="org.springframework.aop.framework.ProxyFactoryBean" > <property name ="interceptorNames" > <list > <value > regexPointcutAdvisor</value > </list > </property > <property name ="target" ref ="myLogicClass" /> </bean >
output 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 -------------------- Before method execuation This is from logicMethodOne After method execuation -------------------- Before method execuation This is from logicMethodTwo After method execuation -------------------- This is from testLogic --------------------
In practice, you can use it to manage DAO layer, where you can declare “.*DAO.*” to intercept all your DAO classes to support transaction.