Java動態(tài)代理之攔截器的實現(xiàn)

簡述

  • 前面我們了解了動態(tài)代理以及JDK動態(tài)代理技術,由于動態(tài)代理比較難理解,程序設計者通常會設計一個攔截器接口給開發(fā)人員使用,開發(fā)人員只需要實現(xiàn)該接口并像應用注冊即可。
  • SpringMvc中的攔截器就是這樣,實現(xiàn)org.springframework.web.servlet.HandlerInterceptor接口,然后向配置文件中去注冊該實現(xiàn)類。

代碼案例

本案例所有代碼可到動態(tài)代理之攔截器中去下載

【攔截器接口】

//攔截器接口
import java.lang.reflect.Method;

public interface Interceptor {

    boolean before(Object proxy, Object target, Method method, Object[] args);

    void around(Object proxy, Object target, Method method, Object[] args);

    void after(Object proxy, Object target, Method method, Object[] args);

}

【攔截器實現(xiàn)類】

//攔截器實現(xiàn)類
import java.lang.reflect.Method;

public class MyInterceptor implements Interceptor {
    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("反射方法前邏輯 --- 判斷用戶是否處于登錄狀態(tài) --- 用戶未登錄,操作攔截");
        return false;//不反射被代理對象原有方法,這里true或false根據(jù)開發(fā)人員需求自定義
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("取代了被代理對象的方法 --- 頁面轉(zhuǎn)發(fā)到登錄頁面");
    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        System.err.println("反射方法后的邏輯 --- 記錄本次異常操作");
    }
}

【動態(tài)代理邏輯】

//動態(tài)代理邏輯
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class InterceptorJdkProxy implements InvocationHandler {

    private Object target;//真實對象
    private String interceptorClass = null;//攔截器全限定名

    public InterceptorJdkProxy(Object target, String interceptorClass) {
        this.target = target;
        this.interceptorClass = interceptorClass;
    }


    /**
     * 綁定委托對象,并返回一個【代理占位】
     * @param target 真實對象
     * @param interceptorClass
     * @return 代理對象【占位】
     */
    public static Object bind(Object target, String interceptorClass){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InterceptorJdkProxy(target, interceptorClass));
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(interceptorClass == null){
            //代表沒有設置攔截器,直接反射原有方法
            return method.invoke(target, args);
        }

        Object result = null;

        //通過反射生成攔截器
        Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
        //調(diào)用前置方法
        if(interceptor.before(proxy, target, method, args)){
            result = method.invoke(target, args);
        }else {
            interceptor.around(proxy, target, method, args);
        }

        //調(diào)用后置方法
        interceptor.after(proxy, target, method, args);

        return result;
    }
}

【測試】

//測試
import com.bpf.chapter2.proxy.jdkProxy.HelloWorld;
import com.bpf.chapter2.proxy.jdkProxy.HelloWorldImpl;

public class TestInterceptor {

    public static void main(String[] args) {
        //注冊攔截器
        HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),
                "com.bpf.chapter2.proxy.interceptor.MyInterceptor");
        //不注冊攔截器
        HelloWorld proxy2 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(), null);

        proxy1.sayHelloWorld();
         /*
        結(jié)果
        反射方法前邏輯 --- 判斷用戶是否處于登錄狀態(tài) --- 用戶未登錄,操作攔截
        取代了被代理對象的方法 --- 頁面轉(zhuǎn)發(fā)到登錄頁面
        反射方法后的邏輯 --- 記錄本次異常操作
        */
        proxy2.sayHelloWorld();
         /*
        結(jié)果
        hello world!
        */
    }
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 本文是我自己在秋招復習時的讀書筆記,整理的知識點,也是為了防止忘記,尊重勞動成果,轉(zhuǎn)載注明出處哦!如果你也喜歡,那...
    波波波先森閱讀 12,444評論 6 86
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,940評論 1 92
  • 南樂一曲頌唐音,婉約古風滌紅塵。 若問弦管何處有,花香鬢影園西門。 (記廈門中山公園西門賞南音古樂)
    花影重重閱讀 356評論 0 1
  • D1坐享 時間2018.5.10。 06;39—06:49 時長:十分鐘; 真正關注呼吸:90個呼吸(225秒...
    蕭蕭_健康管理閱讀 216評論 0 0

友情鏈接更多精彩內(nèi)容