Spring基礎(20)——AOP——靜態PointCut
阿新 • • 發佈:2019-02-16
靜態切入點只在代理建立時執行一次,而不是在執行期間每次呼叫方法時都執行,所以效能比動態切入點要好,是首選的切入點方式。
在Spring中定義了兩個靜態切入點的實現類。
StaticMethodMatcherPointcut:一個抽象的靜態Pointcut,它不能被例項化。開發者可以根據自己擴充套件該類來實現自定義的切入點。
NameMatchMethodPointcut:只能對方法名進行判別的靜態Pointcut實現類。
靜態Pointcut例項:
package test.pointcut; public class People { public void speak() { System.out.println("People Speaking"); } public void run() { System.out.println("People Run"); } public void talk() { System.out.println("People Talk"); } }
package test.pointcut; import java.lang.reflect.Method; import org.springframework.aop.ClassFilter; import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor; public class PeopleAdvisor extends StaticMethodMatcherPointcutAdvisor { @Override public boolean matches(Method method, Class<?> targetClass) { // TODO Auto-generated method stub return "speak".equals(method.getName()); } public ClassFilter getClassFilter() { return new ClassFilter() { @Override public boolean matches(Class<?> clazz) { return People.class.isAssignableFrom(clazz); } }; } }
package test.pointcut; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class PeopleBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getSimpleName() + " is " + method.getName() + " !" ); } }
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="peopleTarget" class="test.pointcut.People"></bean>
<bean id="peopleAdvice" class="test.pointcut.PeopleBeforeAdvice"></bean>
<bean id="people"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<idref bean="peopleAdvisor" />
</property>
<property name="target" ref="peopleTarget"></property>
</bean>
<bean id="peopleAdvisor" class="test.pointcut.PeopleAdvisor">
<property name="advice" ref="peopleAdvice"></property>
</bean>
</beans>
package test.pointcut;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-servlet2.xml");
People people = (People) context.getBean("people");
people.speak();
people.talk();
people.run();
}
}
執行結果:
資訊: Loading XML bean definitions from class path resource [spring-servlet2.xml]
People is speak !
People Speaking
People Talk
People Run
正則表示式:
前面的方法通過方法名定義切入點,如果有多個方法需要定義切入點,需要在實現類中多次判斷,如果多個目標的名字有一定的規則,使用正則表示式過濾,將減少許多麻煩。
在Spring中,RegexpMethodPointcutAdvisor是正則表示式方法匹配的切面實現類。該類功能比較全,一般情況下,不需要擴充套件該類,因此也省去了編寫通知的麻煩。
與之前的除了配置有一定差異以外,程式碼都是一樣的。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="peopleTarget" class="test.pointcut.People"></bean>
<bean id="peopleAdvice" class="test.pointcut.PeopleBeforeAdvice"></bean>
<bean id="people"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<idref bean="peopleAdvisor" />
</property>
<property name="target" ref="peopleTarget"></property>
</bean>
<bean id="peopleAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!--
-->
<property name="patterns">
<list>
<value>.*k</value>
</list>
</property>
<property name="advice" ref="peopleAdvice"></property>
</bean>
</beans>
執行結果:
資訊: Loading XML bean definitions from class path resource [spring-servlet2.xml]
People is speak !
People Speaking
People is talk !
People Talk
People Run
在定義切入點是經常使用的正則表示式:
符號 | 描述 | 例項 |
---|---|---|
. | 匹配換行符外的所有單個字元 | setFoo.匹配setFooA,但不匹配setFoo或者setFooArr |
+ | 匹配+號前面的字元1次或者N次 | setFoo.+匹配setFooA和setFooArr,但不匹配setFoo |
* | 匹配*前面的字元0次或者N次 | setFoo.*匹配setFoo、setFooA和setFooArr |
? | 匹配?號前面的字元0次或者1次 | e?le?匹配angel中的el和angle中的le |