1、靜態普通方法名匹配切面
StaticMethodMatcherPointcutAdvisor代表一個靜態方法匹配切面。
package com.smart.advisor;public class Waiter {public void greetTo(String name){System.out.println("Waiter greet to "+name+"...");}public void serveTo(String name){System.out.println("Waiter serving "+name+"...");}}
package com.smart.advisor;public class Seller {public void greetTo(String name){System.out.println("Seller greet to "+name+"...");}}
package com.smart.advisor;import java.lang.reflect.Method;import org.springframework.aop.ClassFilter;import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor{private static final long serialVersionUID = 1L;@Overridepublic boolean matches(Method arg0, Class<?> arg1) {//切點方法匹配規則:方法名為greetTo// TODO Auto-generated method stubreturn "greetTo".equals(arg0.getName());}@Overridepublic ClassFilter getClassFilter() {//切點類匹配匹配規則:為Waiter的類或子類// TODO Auto-generated method stubreturn new ClassFilter() {@Overridepublic boolean matches(Class<?> clazz) {// TODO Auto-generated method stubreturn Waiter.class.isAssignableFrom(clazz);}};}}
package com.smart.advisor;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class GreetingBeforeAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method arg0, Object[] arg1, Object arg2)throws Throwable {// TODO Auto-generated method stubSystem.out.println(arg2.getClass().getName()+"."+arg0.getName());//輸出切點String clientName=(String)arg1[0];System.out.println("How are you ! Mr."+clientName+".");}}
<bean id="waiterTarget" class="com.smart.advisor.Waiter"/><bean id="sellerTarget" class="com.smart.advisor.Seller"/><bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/><bean id="greetingAdvisor" class="com.smart.advisor.GreetingAdvisor"p:advice-ref="greetingAdvice"/><!-- 向切面注入前置加強 --><bean id="parent" abstract="true"class="org.springframework.aop.framework.ProxyFactoryBean"p:interceptorNames="greetingAdvisor"p:proxyTargetClass="true"/><!-- abstract="true" 通過一個父<bean>定義公用的配置資訊 --><bean id="waiter" parent="parent" p:target-ref="waiterTarget"/><!-- waiter代理 --><bean id="seller" parent="parent" p:target-ref="sellerTarget"/><!-- seller代理 -->
package com.smart.advisor;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringAdvisorTest {@Testpublic void testAdvisor(){String configPath="com/smart/advisor/beans.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);Waiter waiter=(Waiter)ctx.getBean("waiter");Seller seller=(Seller)ctx.getBean("seller");waiter.greetTo("TomSon");waiter.serveTo("TomSon");seller.greetTo("TomSon");}}
得到結果:
com.smart.advisor.Waiter.greetTo
How are you ! Mr.TomSon.
Waiter greet to TomSon...
Waiter serving TomSon...
Seller greet to TomSon...
可見,切面只織入Waiter.greetTo()方法調用前的連接點上,Waiter.serveTo()和Seller.greetTo()方法沒有織入切面。
2、靜態Regex方法匹配切面
具體案例:
beans2.xml
<bean id="waiterTarget" class="com.smart.advisor.Waiter"/><bean id="sellerTarget" class="com.smart.advisor.Seller"/><bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/><bean id="regexAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"p:advice-ref="greetingAdvice"><property name="patterns"><!--用Regex定義目標類全限定方法名匹配模式串--><list><value>.*greet.*</value><!-- 匹配模式串 --></list></property></bean><bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean"p:interceptorNames="regexAdvisor"p:target-ref="waiterTarget"p:proxyTargetClass="true"/>
定義了一個匹配模式串".*greet.*",該模式串匹配Waiter.greetTo()方法。
測試資料:
package com.smart.advisor;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringAdvisorTest {@Testpublic void testAdvisor(){String configPath="com/smart/advisor/beans2.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);Waiter waiter=(Waiter)ctx.getBean("waiter1");waiter.greetTo("Tom");waiter.serveTo("Tom");}}
顯示結果是:
com.smart.advisor.Waiter.greetTo
How are you ! Mr.Tom.
Waiter greet to Tom...
Waiter serving Tom...
3、自動建立代理:
BeanNameAutoProxyCreator執行個體:
beans3.xml
<bean id="waiterTarget" class="com.smart.advisor.Waiter"/><bean id="sellerTarget" class="com.smart.advisor.Seller"/><bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"p:beanNames="*erTarget"p:interceptorNames="greetingAdvice"p:optimize="true"/>
測試資料:
package com.smart.advisor;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringAdvisorTest {@Testpublic void testAdvisor(){String configPath="com/smart/advisor/beans3.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);Waiter waiter=(Waiter)ctx.getBean("waiterTarget");Seller seller=(Seller)ctx.getBean("sellerTarget");waiter.greetTo("John");seller.greetTo("Tom");}}
結果資料是:
com.smart.advisor.Waiter.greetTo
How are you ! Mr.John.
Waiter greet to John...
com.smart.advisor.Seller.greetTo
How are you ! Mr.Tom.
Seller greet to Tom...
DefaultAdvisorAutoProxyCreator執行個體:
DefaultAdvisorAutoProxyCreator能夠掃描容器中的Advisor,並將Advisor自動織入匹配的目標Bean中,即為匹配的目標Bean自動建立代理。
beans4.xml
<bean id="waiterTarget" class="com.smart.advisor.Waiter"/><bean id="sellerTarget" class="com.smart.advisor.Seller"/><bean id="greetingAdvice" class="com.smart.advisor.GreetingBeforeAdvice"/><bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"p:patterns=".*greet.*"p:advice-ref="greetingAdvice"/><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/><!-- 用DefaultAdvisorAutoProxyCreator定義一個Bean,他負責將容器中的Advisor織入匹配的目標Bean中。 -->
測試資料:
package com.smart.advisor;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringAdvisorTest {@Testpublic void testAdvisor(){String configPath="com/smart/advisor/beans4.xml";ApplicationContext ctx=new ClassPathXmlApplicationContext(configPath);Waiter waiter=(Waiter)ctx.getBean("waiterTarget");Seller seller=(Seller)ctx.getBean("sellerTarget");waiter.serveTo("John");waiter.greetTo("John");seller.greetTo("Tom");}}
得到的結果是:
Waiter serving John...
com.smart.advisor.Waiter.greetTo
How are you ! Mr.John.
Waiter greet to John...
com.smart.advisor.Seller.greetTo
How are you ! Mr.Tom.
Seller greet to Tom...