2022年1月27日 星期四

[Geroge]設計模式-Java動態代理

靜態代理: 自己手寫的代理類, 程序運行前就已經存在的編譯好的代理類 by Geroge

反之~如果代理類程序運行之前並不存在, 需要在程序運行時動態生成(無須手工編寫代理類源碼), 那就是今天要說的動態代理了

如何生成的: 根據Java的反射機制動態生成

*****

Java動態代理(Dynamic Proxy)

在java中, 通常使用Proxy(動態代理)來實現對代理模式的支持

Java中要創建一個代理對象, 必須調用Proxy類的靜態方法newProxyInstance,該方法的原型如下

Object Proxy.newProxyInstance(ClassLoader loader, class<?>[]interfaces, InvacationHandler handler) throws IllegalArgumentExcetion

其中: 

loader: 表示類加載器, 對於不同來源(系統庫或網路等)的類需要不同的類加載器來加載, 這是Java安全模型的一部分

interfaces: 它就是被代理對象共有的介面

handler : 表示調用處理器, 它必須是實現了InvocationHandler介面的對象, 其作用是定義代理對象中需要執行的具體操作, InvocationHandler 之於Proxy, 就如Runnable之於Thread, InvocationHandler 介面中只有一個方法Invoke, 它的作用就跟Runnable中的run方法類似, 定義了代理對象在執行真實對象的方法時所希望執行的動作, 其原型如下:

Object invoke(Object proxy, Method method, Object[] args)throws Throwable

其中

proxy: 表示執行這個方法的代理對象

method: 表示真實對象實際需要執行的方法(關於Method類參見Java的反射機制)

args: 表示真實對象實際執行方法時所需的參數

例子: 

例如我們有一個KFC介面, 還有它的實現, 也有miseller介面, 和它的實現



















我們造一個Handler類別去實行InvocationHandler類別
生一個區域變數realObject, 當初始化時傳進來
下面方法調用invoke的時候它再invoke找realSubject做事










而它在使用上, 可以用Proxy. newProxyInstnce傳入當前class.getClassLoader, 第二個參數有兩種寫法如下new Class[]{將使用的介面}, 或是將使用的介面.class.getInterfaces(), 最後再new ProxyHandler類別出來將要使用的實現類別塞入




















總結
Proxy已經設計優美, 但是它有小缺憾, 始終無法擺脫interface代理, 基於代理他們已經注定有一個共同父類Proxy, 這個機制注定了動態代理類無法對class的動態代理, 原因是多重繼承無法通行
那類的動態代理有CGLib, Aspectj可以再更深入學習

https://www.youtube.com/watch?v=cA-vt0Nf1nQ&list=PLGmd9-PCMLhb16ZxeSy00qUsBazXgJyfM&index=16

https://github.com/iw5420/geroge-design-pattern


沒有留言:

張貼留言

創業想法1

現在有駐點工作的公司 今天突然想到 那為什麼沒有遠端駐點公司 就是接國外的職位 幫他找台灣人 在公司上遠端工作的職缺 有可能是因為時差 所以這種公司上班時間不同, 並不好管理 但是感覺理論上是存在需求 就是台灣人想找遠端職缺, 但是可能語言上或技能上還差點火候 公司提供培訓, 並...