下面以JdkRegexpMethodPointcut為例,通過一個完整的范例展示如何使用靜態切入點(完整工程代碼見例程4.3)。在工程中我們定義一個People類和一個切面,並將他們在Spring xml配置文件中聯系起來。當People對象執行我們切入點中定義的方法時,前置裝備LogerPeople將會給出相應的提示信息。
新建一個工程AOP_Test4.3,添加Spring開發庫後,新建aop.test包。
創建目標類People,該類有speak、Running、Loving、died四個成員方法。代碼如下:
代碼
/**
*
*/
package aop.test;
/**
* @author zhangyong
*
*/
public class People{
// 講話
public void speak() {
System.out.println("Hello,我是People!");
}
// 跑步
public void Running() {
System.out.println("我在跑……跑…………逃……");
}
// 戀愛
public void Loving() {
System.out.println("我在和MM戀愛……別來打攪我!");
}
// 死亡
public void died() {
System.out.println("完了,我死了");
}
}
創建一個類名為LogerPeople的前置裝備,它實現MethodBeforeAdvice接口,在before方法中利用Log4J輸出相關信息,代碼如下:
代碼
/**
*
*/
package aop.test;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
/**
* @author zhangyong
*
*/
public class LogerPeople implements MethodBeforeAdvice {
private static final Log log = LogFactory.getLog(LogerPeople.class);
public void before(Method method, Object[] args, Object target)
throws Throwable {
// 這裡什麼也不做,只是利用Log4J輸出日志信息
log.info(target.getClass().getSimpleName() + "正在" +
method.getName()+ "!");
}
}
/**
*
*/
package aop.test;
import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.MethodBeforeAdvice;
/**
* @author zhangyong
*
*/
public class LogerPeople implements MethodBeforeAdvice {
private static final Log log = LogFactory.getLog(LogerPeople.class);
public void before(Method method, Object[] args, Object target)
throws Throwable {
// 這裡什麼也不做,只是利用Log4J輸出日志信息
log.info(target.getClass().getSimpleName() + "正在" +
method.getName()+ "!");
}
}
再編寫Spring配置文件,完成後如下:
代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="Computer" class="aop.test.People"></bean>
<bean id="LogerComputer" class="aop.test.LogerPeople" />
<bean id="ProxyFactoryBean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="Computer" />
</property>
<property name="interceptorNames">
<list>
<value>DefaultAdvisor</value>
</list>
</property>
</bean>
<bean id="DefaultAdvisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut" ref="JdkRegexpPointcut" />
<property name="advice" ref="LogerComputer" />
</bean>
<bean id="JdkRegexpPointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>.*spea.*</value>
<value>.*ing</value>
<value>.*di.*</value>
</list>
</property>
<property name="excludedPattern" value=".*Run.*" />
</bean>
</beans>
為了讓ProxyFactoryBean使用我們定義的JdkRegexpMethodPointcut而不是默認的Pointcut,我們需要配置一個切入點配置器PointcutAdvisor,其advice屬性指定裝備,Pointcut屬性指定切入點。然後再將該切入點配置器注入給ProxyFactoryBean。各個Bean的依賴關系和說明如下:
圖4.4 ProxyFactoryBean代理生成
在JdkRegexpMethodPointcut中,我們使用了它兩個屬性patterns和excludedPattern:patterns利用正則表達式指定了我們要監視的方法這裡是包含了所有的方法;excludedPattern指定了我們要排除的方法,這裡指定了以Run開頭的方法。
注意:
1)“.*spea.*”表示所有名字以spea開頭的方法,例程中是指speak方法;
2)“.*ing”表示所有名字以ing結束的方法,例程中是指Running和Loving方法;
3)“.*di.*”表示所有名字以di開頭的方法,例程中是指died方法;
4)“.*Run.*”表示所有名字以Run開頭的方法,例程中是指Running方法;
創建含主方法的測試類TestMain,在一種我們從ProxyFactoryBean中獲得People實例對象,並一次調用該對象的方法,代碼如下:
代碼 /**
*
*/
package aop.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author zhangyong
*
*/
public class TestMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"applicationContext.xml");
//通過ProxyFactoryBean獲取IComputer接口實現類的實例
People c = (People) ac.getBean("ProxyFactoryBean");
c.speak();
c.Running();
c.Loving();
c.died();
}
}
該類運行結果如下:
圖4.5 例程4.3運行結果
可以看到People類中的speak、Loving、died方法已經被攔截。但是Running方法卻沒有攔截,這是因為我們在JdkRegexpMethodPointcut中指定其excludedPattern屬性把它排除在切入點之外的緣故。
本文地址:http://www.blogjava.net/cmzy/archive/2008/08/10/220917.html)