所谓Spring静态切入点,相对于动态切入点来说,具有良好的性能,因为静态切入点只在代理创建时候执行一次,而不是在运行期间,每次目标方法执行前都进行执行,下面,以实例说明如何定义静态切入点
看我我前一篇blog的朋友都知道,如果不定义切入点,通知方法是会对整个目标类的所有方法均进行切入的
但实际需求中,我们可能对其中的几个方法执行A通知,对其他的方法执行B通知,这时候,就需要通过定义不同的切入点来进行区分
目标接口:
public interface Shopping {
public String buySomething(String type);
public String buyAnything(String type);
public String sellSomething(String type);
public String sellAnything(String type);
}
javabean:
public class Customer {
private String name;
private String age;
public Customer() {
}
public Customer(String name,String age) {
this .name = name;
this .age = age;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this .age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
}
业务目标实现类:
public class ShoppingImpl implements Shopping {
private Customer customer;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this .customer = customer;
}
public String buySomething(String type) {
System.out.println( this .getCustomer().getName() + " bye " + type + " success " );
return null ;
}
public String buyAnything(String type) {
System.out.println( this .getCustomer().getName() + " bye " + type + " success " );
return null ;
}
public String sellAnything(String type) {
System.out.println( this .getCustomer().getName() + " sell " + type + " success " );
return null ;
}
public String sellSomething(String type) {
System.out.println( this .getCustomer().getName() + " sell " + type + " success " );
return null ;
}
}
通知(切面)方法:
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
// 前置通知
public class WelcomeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object obj)
throws Throwable {
String type = (String)args[ 0 ];
System.out.println( " Hello welcome to buy " + type);
}
}
下面是重点,我们想对所有的buy方法进行通知处理,也就是在所有的buy方法上定义切面
spring为我们创建了静态切入点的父类 StaticMethodMatcherPointCut ,如果我们想实现自制的静态切入点,只要继承这个类就可以了,不过一般情况下,我们使用spring提供的静态切入点NameMatchMethodPointCut就足够了
配置文件如下:
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
< bean id ="customer" class ="StaticAdvisorTest.Customer" >
< constructor-arg index ="0" >
< value > gaoxiang </ value >
</ constructor-arg >
< constructor-arg index ="1" >
< value > 26 </ value >
</ constructor-arg >
</ bean >
< bean id ="shoppingImpl" class ="StaticAdvisorTest.ShoppingImpl" >
< property name ="customer" >
< ref local ="customer" />
</ property >
</ bean >
<!-- 定义通知 -->
< bean id ="shoppingAdvise" class ="StaticAdvisorTest.WelcomeAdvice" ></ bean >
<!-- 定义切入点 -->
< bean id ="shoppingPointCutAdvisor" class ="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" >
< property name ="mappedName" >
< value > sell* </ value >
</ property >
< property name ="advice" >
< ref bean ="shoppingAdvise" />
</ property >
</ bean >
<!-- 定义代理 -->
< bean id ="StaticAdvisorTest" class ="org.springframework.aop.framework.ProxyFactoryBean" >
< property name ="proxyInterfaces" >
< value > StaticAdvisorTest.Shopping </ value >
</ property >
< property name ="interceptorNames" >
< list >
< value > shoppingPointCutAdvisor </ value >
</ list >
</ property >
< property name ="target" >
< ref bean ="shoppingImpl" />
</ property >
</ bean >
</ beans >
<!-- 如果不使用通配符,则用以下表达
<property name="mappedNames">
<list>
<value>sellSomething</value>
<value>sellAnything</value>
</list>
</property>
-->
测试程序:
import java.io.File;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class TestAdvisor {
public static void main(String[] args) {
String filePath = System.getProperty( " user.dir " ) + File.separator + " StaticAdvisorTest " + File.separator + " hello.xml " ;
BeanFactory factory = new XmlBeanFactory( new FileSystemResource(filePath));
Shopping shopping = null ;
shopping = (Shopping)factory.getBean( " StaticAdvisorTest " );
shopping.buySomething( " something " );
shopping.buyAnything( " anything " );
shopping.sellAnything( " anything " );
shopping.sellSomething( " something " );