浅谈Spring静态切入点使用方法[转]
所谓Spring静态切入点,相对于动态切入点来说,具有良好的性能,因为静态切入点只在代理创建时候执行一次,而不是在运行期间,每次目标方法执行前都进行执行,下面,以实例说明如何定义静态切入点
?
看我我前一篇blog的朋友都知道,如果不定义切入点,通知方法是会对整个目标类的所有方法均进行切入的
但实际需求中,我们可能对其中的几个方法执行A通知,对其他的方法执行B通知,这时候,就需要通过定义不同的切入点来进行区分
目标接口:
?
package?StaticAdvisorTest;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
public?interface?Shopping?...{
??public?String?buySomething(String?type);
??public?String?buyAnything(String?type);
??public?String?sellSomething(String?type);
??public?String?sellAnything(String?type);![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
?javabean:
?
package?StaticAdvisorTest;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
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;
}
}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
?
业务目标实现类:
?
package?StaticAdvisorTest;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
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;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
?????}
????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;
????}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
?
通知(切面)方法:
?
package?StaticAdvisorTest;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
import?java.lang.reflect.Method;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
import?org.springframework.aop.MethodBeforeAdvice;
//前置通知
public?class?WelcomeAdvice?implements?MethodBeforeAdvice?...{![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
????public?void?before(Method?method,?Object[]?args,?Object?obj)
????????????throws?Throwable?...{
????????String?type=(String)args[0];
????????System.out.println("Hello?welcome?to?buy?"+type);![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
????}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
}![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
?
下面是重点,我们想对所有的buy方法进行通知处理,也就是在所有的buy方法上定义切面
spring为我们创建了静态切入点的父类 StaticMethodMatcherPointCut ,如果我们想实现自制的静态切入点,只要继承这个类就可以了,不过一般情况下,我们使用spring提供的静态切入点NameMatchMethodPointCut就足够了
配置文件如下:
?
<?xml?version="1.0"?encoding="UTF-8"?>
<!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>![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
</beans>![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
?<!-- 如果不使用通配符,则用以下表达
? <property name="mappedNames">
??? <list>
?????? <value>sellSomething</value>
?????? <value>sellAnything</value>
??? </list>
? </property>
? -->
测试程序:
?
package?StaticAdvisorTest;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
import?java.io.File;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
import?org.springframework.beans.factory.BeanFactory;
import?org.springframework.beans.factory.xml.XmlBeanFactory;
import?org.springframework.core.io.FileSystemResource;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327863.gif)
public?class?TestAdvisor?...{![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
????public?static?void?main(String[]?args)?...{![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
????????String?filePath=System.getProperty("user.dir")+File.separator+"StaticAdvisorTest"+File.separator+"hello.xml";
????????
????????BeanFactory?factory=new?XmlBeanFactory(new?FileSystemResource(filePath));
????????
????????Shopping?shopping=null;![浅谈Spring静态突破点使用方法[转]](http://img.reader8.net/uploadfile/jiaocheng/20140188/3013/20140130131327866.gif)
????????shopping=(Shopping)factory.getBean("StaticAdvisorTest");
????????shopping.buySomething("something");
????????shopping.buyAnything("anything");
????????shopping.sellAnything("anything");
????????shopping.sellSomething("something");
????????