在WEB開發中,用戶對網頁的訪問權限檢查是一個重要的環節。以STRUST爲例,我們需要在Action的excute方法中編寫相關的代碼(一般是調用基類的函數),也很顯然,在每個Action中這是一種重複勞動。
如果我們在excute運行之前,能夠自動去調用基類的權限檢查函數,這無疑是個好的解決辦法。AOP就爲我們提供了這樣一種解決方法。
下面以一個簡化的實例介紹實現的辦法。
首先我們做一個接口:
|
再做一個基類:
public abstract class BaseClass implements CheckInterface {
public BaseClass() {
}
public void check(String name){
if (name.equals("supervisor"))
System.out.println("Check Pass!!");
else {
System.out.println("No access privilege! Please do sth. else!");
}
}
}
再做一個測試類:
public class ExcuteClass extends BaseClass {
public ExcuteClass() {
}
public void excute(String name){
System.out.println("Excute here!"+name);
}
}
好了,下面做一個通知類(Advice):
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
public class BeforeAdvisor implements MethodBeforeAdvice {
private static Logger logger=Logger.getLogger(BeforeAdvisor.class);
public void before(Method m, Object[] args, Object target) throws Throwable {
if (target instanceof CheckInterface){
logger.debug("Is Instanceof CheckInterface!!!");
CheckInterface ci=(CheckInterface)target;
ci.check((String)args[0]);
}
}
}
其中重要的before方法的參數:Object target傳入的通知的對象(即測試類的接口),Method m, Object[] args分別是該對象被調用的方法和參數。
我們再來作spring bean定義xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "">http://www.springframework.org/dtd/spring-beans.dtd">; <beans> <description>Spring Quick Start</description> <bean id="MyAdvisor" class="com.wysm.netstar.test.springaop.BeforeAdvisor"/> <bean id="myPointcutAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="MyAdvisor" /> </property> <property name="patterns"> <list> <value>.*excute.*</value> </list> </property> </bean> <bean id="checkInterface" class="com.wysm.netstar.test.springaop.ExcuteClass"/> <bean id="myCheckClass" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.wysm.netstar.test.springaop.CheckInterface</value> </property> <property name="target"> <ref local="checkInterface" /> </property> <property name="interceptorNames"> <value>myPointcutAdvisor2</value> </property> </bean> </beans> |
這個定義文件指明瞭ExcuteClass爲監視對象,它的excute方法被執行的時候,BeforeAdvisor將被調用。
最後是測試類:
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class SpringTestCase2 extends TestCase {
CheckInterface test=null;
protected void setUp() throws Exception {
super.setUp();
ApplicationContext ctx=new FileSystemXmlApplicationContext("src/com/wysm/netstar/test/springaop/aoptest.xml");
test = (CheckInterface) ctx.getBean("myCheckClass");
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testExcute(){
test.excute("supervisor");
}
}