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.javaTargetInterceptor.java 並沒有關連

 

Step 03: 建立 java.lang.reflect.InvocationHandler :TargetHandler.java  , 利用 invoke(Object proxy, Method method, Object[] args) 方法讓 TargetImpl.javaTargetInterceptor.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 間接讓 InvocationHandlerinvoke() 方法,使得 目標對象 Object: TargetProvider target 與攔截器 Interceptor 攔截器:TargetInterceptor 產生關連 ,因此可以作到我們想要攔截到目標對象時,想要多作的作業。

 

arrow
arrow
    創作者介紹
    創作者 MIS 的頭像
    MIS

    MISTECH 技術手抄本

    MIS 發表在 痞客邦 留言(1) 人氣()