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;
@Override
public boolean matches(Method arg0, Class<?> arg1) {
//切點方法匹配規則:方法名為greetTo
// TODO Auto-generated method stub
return "greetTo".equals(arg0.getName());
}
@Override
public ClassFilter getClassFilter() {
//切點類匹配匹配規則:為Waiter的類或子類
// TODO Auto-generated method stub
return new ClassFilter() {
@Override
public boolean matches(Class<?> clazz) {
// TODO Auto-generated method stub
return Waiter.class.isAssignableFrom(clazz);
}
};
}
}
package com.smart.advisor;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class GreetingBeforeAdvice implements MethodBeforeAdvice
{
@Override
public void before(Method arg0, Object[] arg1, Object arg2)
throws Throwable {
// TODO Auto-generated method stub
System.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
{
@Test
public 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、静态正则表达式方法匹配切面
具体事例:
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"><!--用正则表达式定义目标类全限定方法名匹配模式串-->
<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
{
@Test
public 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
{
@Test
public 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
{
@Test
public 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...