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 產生關連 ,因此可以作到我們想要攔截到目標對象時,想要多作的作業。
留言列表