Struts 2 在 struts2-core-2.x.x.jar 的 struts-default.xml 中也設定了許多的 Interceptor 攔截器,Interceptor 攔截器的基本概念大致整理如下:
1. 要有目標對象
2. 攔截器本身,在攔截器本身安插要執行的作業
3. 由 java.lang.reflect.InvocationHandler 來讓 目標對象 與 攔截器 產生關連
4. 由 代理 java.lang.reflect.Proxy 來執行,用來產生動態對象
依上面的概念來實作如下:
Step 01: 建立一個 Interface: TargetProvider.java 及實作它: TargetImpl.java
TargetProvider.java
package com.test.interceptor;
public interface TargetProvider {
public void doExecute();
} |
TargetImpl.java
package com.test.interceptor;
public class TargetImpl implements TargetProvider {
@Override
public void doExecute() {
// TODO Auto-generated method stub
System.out.println("do Execute");
}
} |
Step 02: 建立Interceptor 攔截器本身:TargetInterceptor.java,並在攔截器本身安撰寫想要執行的作業
package com.test.interceptor;
public class TargetInterceptor {
public void beforeExecute(){
System.out.println("before Execute");
}
public void afterExecute(){
System.out.println("after Execute");
}
} |
由上可以得知,目前 TargetImpl.java 與 TargetInterceptor.java 並沒有關連
Step 03: 建立 java.lang.reflect.InvocationHandler :TargetHandler.java , 利用 invoke(Object proxy, Method method, Object[] args) 方法讓 TargetImpl.java 與 TargetInterceptor.java 兩者產生關連
TargetHandler.java
package com.test.interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TargetHandler implements InvocationHandler {
private Object object;
private TargetInterceptor targetInterceptor = new TargetInterceptor();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result = null;
targetInterceptor.beforeExecute();
result = method.invoke(object, args);
targetInterceptor.afterExecute();
return result;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
|
Step 04: 再透過 java.lang.reflect.Proxy: TargetProxy.java 的代理(Proxy) 動態產生新的 ProxyInstance,來執行攔截器作業
package com.test.interceptor;
import java.lang.reflect.Proxy;
public class TargetProxy {
public Object getProxy(Object object){
TargetHandler targetHandler = new TargetHandler();
targetHandler.setObject(object);
return Proxy.newProxyInstance(TargetImpl.class.getClassLoader(), object.getClass().getInterfaces(), targetHandler);
}
}
|
step 05: 最後建立一個 Class: Client.java 來作測試
package com.test.interceptor;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
TargetProvider target = new TargetImpl();
TargetProxy targetProxy = new TargetProxy();
TargetProvider proxy = (TargetProvider) targetProxy.getProxy(target);
proxy.doExecute();
}
}
|
執行 Class: Client 的結果如下:
before Execute
do Execute
after Execute |
所以可以得知:在目標對象 Object: TargetProvider target ,透過代理 Proxy: TargetProxy targetProxy 執行時,會動態產生新的 ProxyInstance,並藉由動態產生新的 ProxyInstance 間接讓 InvocationHandler 的 invoke() 方法,使得 目標對象 Object: TargetProvider target 與攔截器 Interceptor 攔截器:TargetInterceptor 產生關連 ,因此可以作到我們想要攔截到目標對象時,想要多作的作業。