JDK動態代理筆記,學習框架必備知識,學習框架之前先學一下這個
目錄
-
原理
-
基於反射機制
-
a想要訪問c,但是a沒有訪問c的許可權;這是可在a、c之間建立一個可以被a訪問且能訪問c的b;a就可以通過訪問b,讓b去訪問c,間接訪問c;並且還可以在b上實現更多的業務
-
-
暫時的掌握程度
-
先做了解,之後學mybatis和spring再學習怎麼用
-
知道是什麼動態代理?
-
知道動態代理能做什麼?
-
-
動態代理模式的作用
-
功能增強:在原有基礎上增加新功能;除了介面的實現功能外,其他功能都是增強功能
-
控制訪問:代理類可不讓你訪問目標
-
-
靜態代理
-
需要手動實現,建立一個Java類來作為代理類
-
優缺點:
-
優點:實現簡單、容易理解
-
缺點:代理類過多、難修改(需要一個個修改)
-
-
例子
-
需求:模擬一個使用者購買某品牌U盤
-
使用者是客戶端類;商家是代理類,代理某品牌的U盤;廠家是目標類
-
商家和廠家都是賣U盤的,他們完成的功能是一致的,都是賣U盤
-
-
實現步驟:
-
建立一個介面,定義賣U盤的方法,表示你的廠家和商家做的事情
-
建立廠家類,實現步驟1的介面
-
建立商家類(代理類),同樣要實現步驟1的介面
-
建立客戶端類,呼叫商家的方法買U盤
-
-
-
-
動態代理
-
什麼是動態代理:
-
使用jdk的反射機制,建立物件的能力,建立的是代理類的物件。不需要我們建立類檔案
-
動態:在程式執行時,呼叫jdk提供的方法才能建立代理類的物件
-
-
優點:
-
避免了靜態代理的缺點,代理類數量可以很少,修改介面中的方法時不會影響代理類
-
-
實現:
-
在程式執行過程中,使用jdk的反射機制,建立代理類物件,並動態的指定要代理的目標類
-
簡而言之:不用建立代理類就能夠建立代理物件(介面--->物件)
-
注意:學框架再學實現
-
-
-
動態代理的分類
-
jdk動態代理(理解)
-
使用Java反射包中的類和介面實現動態代理的功能
-
Java反射包的三個類:InvocationHandler、Method、Proxy
-
-
ogLib動態代理(瞭解)
-
ogLib是第三方工具庫,使用該工具庫來建立代理物件
-
ogLib的原理是繼承和重寫方法。通過繼承目標類建立它的子類,在子類中重寫父類中同名的方法,實現功能的修改
-
因為ogLib的機制是繼承和重寫方法,所以要求目標類和方法不能是final的(要求寬鬆,能繼承即可)
-
ogLib在很多框架中使用
-
-
-
Method類的複習(其實是預習)
-
invoke()方法
-
是Method類的一個方法,表示執行方法的呼叫(用來呼叫方法)
-
引數:引數1:Object,表示這個物件要執行的方法; 引數2:Object...,方法執行時的引數值
-
返回值:Object,方法執行的返回值
-
-
程式碼展示
-
純淨版
-
-
public static void main(String[] args) throws Exception {
HelloService target = new HelloServiceImpl();
Method method = HelloService.class.getMethod("sayHello", String.class);
Object ret = method.invoke(target, "李四");
}
-
有註釋筆記版
// 使用反射機制執行sayHello方法。核心Method類中的方法
public static void main(String[] args) throws Exception {
// 建立一個需要執行方法的物件
HelloService target = new HelloServiceImpl();
// 獲取sayHello名稱對應的Method類物件
// 引數1:需要獲取的物件的名稱(方法名稱); 引數2:該方法引數的資料型別
Method method = HelloService.class.getMethod("sayHello", String.class);
// 通過Method物件執行target的sayHello方法
/*
invoke是Method類的一個方法,表示執行方法的呼叫(用來呼叫方法)
引數:引數1:Object,表示要執行的方法的物件; 引數2:Object...,方法執行時的引數值
返回值:Object,方法執行的返回值
*/
// 需要執行sayHello方法的物件是target,方法的引數是“李四”(執行target的sayHello方法,引數是“李四”)
Object ret = method.invoke(target, "李四");
}
-
三個類的介紹
-
Java反射包(java.lang.reflect)的三個類:InvocationHandler、Method、Proxy
-
InvocationHandler介面(呼叫處理器)
-
InvocationHandler介面用來表示代理要乾的事情
-
invoke()方法(該介面只有一個方法)
-
invoke()方法表示代理物件要執行的功能程式碼。代理類要完成的功能寫在invoke()方法裡面。
-
代理類完成的功能:
-
呼叫目標方法,執行目標方法的功能
-
功能增強,在目標方法呼叫時,增加功能
-
-
方法原型:public Object invoke(Object proxt, Method method, Object[] args){...}
-
引數分析:(第一個引數不需要賦值,傳遞後兩個引數即可)
-
Object proxt:jdk建立的代理物件,無需賦值(這個引數不需要我們賦值)
-
Method method:目標類中的方法,jdk提供method物件
-
Object[] args:目標類中方法的引數
-
-
-
使用方式:
-
建立InvocationHandler介面的實現類
-
重寫invoke()方法,把要實現的功能寫在該方法裡
-
-
-
-
Method類
-
Method類用來表示目標類中的方法,可用於呼叫invoke方法來執行方法
-
作用:通過Method類可以執行某個目標類的方法Method.invoke(目標物件, 方法引數)
-
-
Proxy類
-
Proxy類用來建立代理物件,Proxy類物件是核心的物件。常規建立物件是“new 類的構造方法”,現使用Proxy類的方法來代替new
-
newProxyInstance()靜態方法
-
作用:建立代理物件
-
方法原型:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
-
ClassLoader loader:類載入器,負責向記憶體中載入物件,使用反射獲取物件的ClassLoader
-
Class<?>[] interfaces:通過反射獲取的目標物件的類所實現的介面
-
InvocationHandler h:代理類要完成的功能,我們自己寫(就是InvocationHandler介面的實現類,重寫的invoke方法包含了要實現的功能)
-
返回值:代理物件
-
-
-
-
-
實現動態代理的步驟
-
建立介面,定義目標類要完成的功能
-
建立目標類實現介面
-
建立InvocationHandler介面的實現類,在invoke()方法中完成代理類的功能
-
呼叫目標方法
-
增強功能
-
-
使用Proxy類的靜態方法建立代理物件,並把代理物件轉為介面型別
-
程式碼展示
-
建立介面
-
-
package com.bjpowenode.service;
// 目標介面
public interface UsbSell {
//
float sell(int amount);
}
-
建立目標類實現介面
package com.bjpowenode.factory;
import com.bjpowenode.service.UsbSell;
public class UsbKingFactory implements UsbSell {
@Override
public float sell(int amount) {
System.out.println("目標類中,執行sell目標方法");
return 85.0f;
}
}
-
建立InvocationHandler介面的實現類
package com.bjpowenode.handler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 實現InvocationHandler介面,完成代理類要做的功能(呼叫目標方法、功能增強)
public class MySellHandler implements InvocationHandler {
private Object target = null;
// 動態代理:目標物件是活動的,不是固定的,需要傳入進來。傳入誰,就給誰建立代理
public MySellHandler(Object target){
// 給目標物件賦值
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 定義一個變數,等會接受執行方法時的返回值
Object res = null;
// 執行目標方法,獲取返回值
res = method.invoke(target, args); // 執行目標方法
// 加價
if (res != null) {
Float price = (Float)res;
price = price + 25;
res = price;
}
// 在目標類的方法呼叫後,實現其他功能,即功能增強
System.out.println("您獲得一個返利紅包");
// 返回加價後的價格
return res;
}
}
-
建立代理物件,並執行功能
package com.bjpowenode;
import com.bjpowenode.factory.UsbKingFactory;
import com.bjpowenode.handler.MySellHandler;
import com.bjpowenode.service.UsbSell;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class MsinShop {
public static void main(String[] args) {
// 使用Proxy類的靜態方法建立代理物件,並把代理物件轉為介面型別
// 1、建立目標物件
UsbSell factory = new UsbKingFactory();
// 2、建立InvocationHandler物件
InvocationHandler handler = new MySellHandler(factory);
// 3、建立代理物件。
// getClass()方法是獲取物件的類, getInterfaces()方法是獲取類所實現的介面
// getClassLoader()方法是獲取這個類的載入器(類載入器負責讀取 Java 位元組程式碼,並轉換成 java.lang.Class類的一個例項。)
UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
factory.getClass().getInterfaces(),
handler);
// 4、通過代理執行方法
float price = proxy.sell(1);
System.out.println("通過動態代理物件呼叫方法:" + price);
}
}
-
注意
-
jdk動態代理,必須有介面,目標型別實現介面,沒有介面時,需要使用cglib動態代理
-
相關文章
- 【筆記】動手學深度學習-預備知識筆記深度學習
- java反射之動態代理學習筆記Java反射筆記
- 深度學習框架Pytorch學習筆記深度學習框架PyTorch筆記
- 機器學習之必備知識篇機器學習
- Bootstrap框架:學習筆記boot框架筆記
- 機器學習框架ML.NET學習筆記【9】自動學習機器學習框架筆記
- go學習筆記——gin框架Go筆記框架
- Scrapy 框架 (學習筆記-1)框架筆記
- Spring框架學習筆記(1)Spring框架筆記
- 機器學習學習筆記——基本知識機器學習筆記
- Java學習筆記之----------Java基本知識Java筆記
- 深度學習開發必備開源框架深度學習框架
- Gin學習筆記01 框架使用筆記框架
- React Native框架探索學習筆記React Native框架筆記
- 好程式設計師Java學習路線之Spring框架之動態代理程式設計師JavaSpring框架
- 基礎知識學習筆記筆記
- 集合框架原始碼學習之HashMap(JDK1.8)框架原始碼HashMapJDK
- 駁 《駁 《駁 《駁 《停止學習框架》》》》、《駁 《駁 《停止學習框架》》》、《駁 《停止學習框架》》、《停止學習框架》框架
- 學習網路BGP必備基礎知識
- 深度學習學習框架深度學習框架
- iOS開發學習筆記:基礎知識之代理模式之老王的故事iOS筆記模式
- 學習網路安全,這些必備基礎知識不能少!
- React學習筆記知識點整理React筆記
- RxJava 學習筆記 -- 基礎知識RxJava筆記
- 22張精煉圖筆記,深度學習專項學習必備筆記深度學習
- Java JDK 9學習筆記JavaJDK筆記
- Android之Mina框架學習Android框架
- 深度學習之Tensorflow框架深度學習框架
- 動態規劃學習筆記動態規劃筆記
- Camera KMD ISP學習筆記(1)-ISP框架筆記框架
- Camera KMD ISP學習筆記(2)-component框架筆記框架
- Jest 測試框架使用的學習筆記框架筆記
- Java | Spring框架學習筆記--(1)工廠JavaSpring框架筆記
- Qt Creator 原始碼學習筆記02,認識框架結構QT原始碼筆記框架
- 機器學習框架ML.NET學習筆記【1】基本概念機器學習框架筆記
- 機器學習框架ML.NET學習筆記【3】文字特徵分析機器學習框架筆記特徵
- JAVA學習筆記及知識積累Java筆記
- 零基礎如何學好大資料?必備需要學習知識大資料