代理模式之JDK動態代理 — 「JDK Dynamic Proxy「

動態代理的原理是什麼?

所謂的動態代理,他是一個代理機制,代理機制能夠看做是對調用目標的一個包裝,這樣咱們對目標代碼的調用不是直接發生的,而是經過代理完成,經過代理能夠有效的讓調用者和實現者之間解耦,常見的代理模式包括:JDK Proxy、cglib。java

JDK動態代理

下面能夠看看JDK動態代理的一個簡單的例子,下面只是加了一句print,在生產系統中,咱們能夠輕鬆擴展相似邏輯進行診斷、限流等。ide

  • 接口Hello
public interface Hello{
    void sayHello();
}
  • 接口的實現類HelloImpl
public class HelloImpl implements Hello {

    @Override
    public void sayHello() {
        System.out.println("Hello JDK Dynamic Proxy!!!");
    }
}
  • DynamicProxyMain類
public class DynamicProxyMain {

    public static void main(String[] args) {
        HelloImpl hello = new HelloImpl();
        JDKDynamicProxy handler = new JDKDynamicProxy(hello);

        //構造代碼實例
        Hello proxyHello = new JDKDynamicProxy(new HelloImpl()).getProxy();
        //使用代理對象調用代理方法
        proxyHello.sayHello();
    }

    /**
     * 建立一個代理類JDKDynamicProxy實現java.lang.reflect.InvocationHandler接口,重寫invoke方法
     */
    static class JDKDynamicProxy implements InvocationHandler{

        private Object target;
        public JDKDynamicProxy(Object target) {
            this.target = target;
        }

        /**
         * 獲取被代理接口實例對象
         * @param <T>
         * @return
         */
        public <T> T getProxy() {
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("正在代理sayHello方法......");
            Object result = method.invoke(target, args);
            return result;
        }
    }
}

運行main函數,結果以下:函數

正在代理sayHello方法......
Hello JDK Dynamic Proxy!!!
  • 上面的JDK Proxy例子,很是簡單地實現了動態代理的構建和代理操做。首先,咱們自定義對應的 JDKDynamicProxy ;而後,以接口Hello爲紐帶,爲被調用目標建立代理對象,進而應用程序就可使用代理對象間接運行調用目標的邏輯,代理爲應用插入額外邏輯(這裏僅僅提供println方法)提供了入口。
  • 不過,JDK動態代理也有必定侷限性,由於必須是以接口爲中心,至關於添 加了一種對於被調用者沒有太大意義的限制。咱們實例化的是 Proxy 對象,而不是真正的 被調用類型,這在實踐中仍是可能帶來各類不便和能力退化。
  • 若是被調用者每個月實現接口,而咱們有但願使用動態代理機制,那麼就能夠考慮使用其餘的方式,好比:Spring AOP支持兩種模式的動態代理,JDK Proxy和cglib,選擇cglib能夠克服對接口的依賴。
相關文章
相關標籤/搜索