1. 程式人生 > 其它 >Java基礎回顧:代理

Java基礎回顧:代理

1)靜態代理 代理模式為其他物件提供一種代理以控制對這個物件的訪問 通過靜態代理,我們達到了功能增強的目的,而且沒有侵入原始碼,這是靜態代理的一個優點。
class Proxy extends Subject { 
  private RealSubject real; 
  @Override 
  public void Request() { 
    if (null == real) { 
    	real = new RealSubject(); 
    } 
  	real.Request(); 
  } 
}
優點:訪問無法訪問的資源,增強現有的介面業務功能 缺點:大量使用這種靜態代理,會使我們系統內的類的規模增大,並且不易維護,這種代理在系統中存在,導致系統結構比較臃腫和鬆散。 2)動態代理 - JDK(通過實現介面的方式)
*** JDK代理是基於實現介面的方式 主要涉及類和介面:
  • java.lang.reflect.Proxy
  • java.lang.reflect.InvovationHandler
動態代理,是需要代理的地方,根據Subject和RealSubject,動態的建立一個Proxy,用完之後,就會銷燬,這樣就可以避免Proxy角色的class在系統中的冗雜問題了。 JDK動態代理步驟:
  • 獲取RealSubject上所有的介面列表;
  • 確定要生成的代理類的類名,預設為:com.sun.proxy.$ProxyXXXX;
  • 根據需要實現的介面資訊,在程式碼中動態建立該Proxy類的位元組碼;
  • 將對應的位元組碼轉換為對應的class物件;
  • 建立 InvocationHandler 例項 handler,用來處理Proxy所有方法呼叫;
  • Proxy的class物件以建立的handler為引數,例項化一個proxy物件。
程式碼例項: 第一步:新建一個UserService介面,以及定義一些方法 第二步:新建一個介面實現類UserServiceImpl,實現介面方法 第三步:新建一個UserHandler類實現InvocationHandler介面 第四步:使用Proxy.newProxyInstance生成代理類 測試 3)動態代理 - CGLib(通過繼承類的方式)
CGLIB建立動態代理類的模式是:
  • 查詢目標類上所有的非final的public型別的方法定義;
  • 將這些方法定義轉成位元組碼;
  • 將組成的位元組碼轉換成相應的代理的class物件;
  • 實現MethodInterceptor介面,用來處理代理類上的所有方法請求
第一步:新建一個類,並定義實現方法 第二步:定義一個類LogInterceptor實現net.sf.cglib.proxy.MethodInterceptor 第三步:定義net.sf.cglib.proxy.Enhancer 結果: 如果要對一個類中不同方法實現不同的攔截策略,實現下面例子: 第四步:再定義一個攔截類 第五步:新增一個類繼承CallbackFilter定義過濾規則(如下,select方法使用第0個攔截,其他方法使用第1個攔截) 第六步:修改Enhancer 結果: 4)JDK和CGLib動態代理對比 JDK動態代理:基於Java反射機制實現,必須要實現了介面的業務類才能使用這種辦法生成代理物件; CGLib動態代理:基於ASM機制(Java 位元組碼操控框架,能夠以二進位制形式修改已有類或者動態生成類)實現,通過生成業務類的子類作為代理類 JDK Proxy優勢:
  • 最小化依賴關係,減少依賴意味著簡化開發和維護,JDK本身支援,可能更可靠;
  • 平滑進行JDK版本升級
  • 程式碼實現簡單
CGLib動態代理優勢:
  • 無需實現介面,達到代理類無侵入
  • 只操作我們關心的類
  • 高效能
參考: https://juejin.cn/post/6844903807755747342 https://juejin.cn/post/6844903744954433544

https://www.cnblogs.com/xrq730/p/6661692.html

一點浩然氣,千里快哉風!