日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

詳解Java的Proxy動態(tài)代理機(jī)制

瀏覽:29日期:2022-08-09 16:36:33
目錄一、Jvm加載對象二、代理模式2.1、基本描述2.2、靜動態(tài)模式三、靜態(tài)代理四、動態(tài)代理4.1、場景描述4.2、基礎(chǔ)API案例4.3、代理類結(jié)構(gòu)4.4、JDK源碼五、源代碼地址一、Jvm加載對象

在說Java動態(tài)代理之前,還是要說一下Jvm加載對象的過程,這個依舊是理解動態(tài)代理的基礎(chǔ)性原理:

詳解Java的Proxy動態(tài)代理機(jī)制

Java類即源代碼程序.java類型文件,經(jīng)過編譯器編譯之后就被轉(zhuǎn)換成字節(jié)代碼.class類型文件,類加載器負(fù)責(zé)讀取字節(jié)代碼,并轉(zhuǎn)換成java.lang.Class對象,描述類在元數(shù)據(jù)空間的數(shù)據(jù)結(jié)構(gòu),類被實例化時,堆中存儲實例化的對象信息,并且通過對象類型數(shù)據(jù)的指針找到類。

過程描述:源碼->.java文件->.class文件->Class對象->實例對象

所以通過New創(chuàng)建對象,獨(dú)斷其背后很多實現(xiàn)細(xì)節(jié),理解上述過程之后,再了解一個常用的設(shè)計模式,即代理模式。

二、代理模式2.1、基本描述

代理模式給某一個(目標(biāo))對象提供一個代理對象,并由代理對象持有目標(biāo)對象的引用。所謂代理,就是一個對象代表另一個對象執(zhí)行相應(yīng)的動作程序。而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用。

詳解Java的Proxy動態(tài)代理機(jī)制

代理模式在實際的生活中場景很多,例如中介、律師、代購等行業(yè),都是簡單的代理邏輯,在這個模式下存在兩個關(guān)鍵角色:

目標(biāo)對象角色:即代理對象所代表的對象。

代理對象角色:內(nèi)部含有目標(biāo)對象的引用,可以操作目標(biāo)對象;AOP編程就是基于這個思想。

2.2、靜動態(tài)模式 靜態(tài)代理:在程序運(yùn)行之前確定代理角色,并且明確代理類和目標(biāo)類的關(guān)系。 動態(tài)代理:基于Java反射機(jī)制,在JVM運(yùn)行時動態(tài)創(chuàng)建和生成代理對象。三、靜態(tài)代理

基于上述靜態(tài)代理的概念,用一段代碼進(jìn)行描述實現(xiàn),基本邏輯如下:

明確目標(biāo)對象即被代理的對象; 定義代理對象,通過構(gòu)造器持有目標(biāo)對象; 代理對象中定義前后置增強(qiáng)方法;

目標(biāo)對象與前后置增強(qiáng)代碼就組成了代理對象,這樣就不用直接訪問目標(biāo)對象,像極了電視劇中那句話:我是律師,我的當(dāng)事人不方便和你對話。

public class Proxy01 { public static void main(String[] args) {TargetObj targetObj = new TargetObj() ;ProxyObj proxyObj = new ProxyObj(targetObj) ;proxyObj.invoke(); }}class TargetObj { public void execute (){System.out.println('目標(biāo)類方法執(zhí)行...'); }}class ProxyObj { private TargetObj targetObj ; /** * 持有目標(biāo)對象 */ public ProxyObj (TargetObj targetObj){this.targetObj = targetObj ; } /** * 目標(biāo)對象方法調(diào)用 */ public void invoke (){before () ;targetObj.execute();after () ; } /** * 前后置處理 */ public void before (){System.out.println('代理對象前置處理...'); } public void after (){System.out.println('代理對象后置處理...'); }}

靜態(tài)代理明確定義了代理對象,即有一個代理對象的.java文件加載到JVM的過程,很顯然的一個問題,在實際的開發(fā)過程中,不可能為每個目標(biāo)對象都定義一個代理類,同樣也不能讓一個代理對象去代理多個目標(biāo)對象,這兩種方式的維護(hù)成本都極高。

代理模式的本質(zhì)是在目標(biāo)對象的方法前后置入增強(qiáng)操作,但是又不想修改目標(biāo)類,通過前面反射機(jī)制可以知道,在運(yùn)行的時候可以獲取對象的結(jié)構(gòu)信息,基于Class信息去動態(tài)創(chuàng)建代理對象,這就是動態(tài)代理機(jī)制。

順便說一句:技術(shù)的底層實現(xiàn)邏輯不好理解是眾所周知,然而基礎(chǔ)知識點并不復(fù)雜,例如代理模式的基本原理,但是結(jié)合到實際的復(fù)雜應(yīng)用中(AOP模式),很難活靈活現(xiàn)的理解到是基于反射和動態(tài)代理的方式實現(xiàn)的。

四、動態(tài)代理4.1、場景描述

基于一個場景來描述動態(tài)代理和靜態(tài)代理的區(qū)別,即最近幾年很火的概念,海外代購:

詳解Java的Proxy動態(tài)代理機(jī)制

在代購剛興起的初期,是一些常去海外出差的人,會接代購需求,即代理人固定;后來就興起海外代購平臺,海淘等一系列產(chǎn)品,即用戶代購需求(目標(biāo)對象)由代購平臺去實現(xiàn),但是具體誰來操作這個就看即時分配,這個場景與動態(tài)代理的原理類似。

4.2、基礎(chǔ)API案例

首先看兩個核心類,這里簡述下概念,看完基本過程再細(xì)聊:

Proxy-創(chuàng)建代理對象,核心參數(shù):

ClassLoader:(目標(biāo)類)加載器; Interfaces:(目標(biāo)類)接口數(shù)組; InvocationHandler:代理調(diào)用機(jī)制;

InvocationHandler-代理類調(diào)用機(jī)制:

invoke:這個上篇說的反射原理; method:反射類庫中的核心API;

目標(biāo)對象和接口

interface IUser { Integer update (String name) ;}class UserService implements IUser { @Override public Integer update(String name) {Integer userId = 99 ;System.out.println('UserId='+userId+';updateName='+name);return userId ; }}

代理對象執(zhí)行機(jī)制

class UserHandler implements InvocationHandler { private Object target ; public UserHandler (Object target){this.target = target ; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println('before()...');Object result = method.invoke(target, args);System.out.println('after()...');return result; }}

具體組合方式

public class Proxy02 { public static void main(String[] args) {/* * 生成$Proxy0的class文件 */System.getProperties().put('sun.misc.ProxyGenerator.saveGeneratedFiles', 'true');/* * 目標(biāo)對象信息 */IUser userService = new UserService();ClassLoader classLoader = userService.getClass().getClassLoader();Class<?>[] interfaces = UserService.class.getInterfaces() ;/* * 創(chuàng)建代理對象 */InvocationHandler userHandler = new UserHandler(userService);/* * 代理類對象名 * proxyClassName=com.java.proxy.$Proxy0 */String proxyClassName = Proxy.newProxyInstance(classLoader,interfaces,userHandler).getClass().getName();System.out.println('proxyClassName='+proxyClassName);/* * 具體業(yè)務(wù)實現(xiàn)模擬 */IUser proxyUser1 = (IUser) Proxy.newProxyInstance(classLoader,interfaces,userHandler);IUser proxyUser2 = (IUser) Proxy.newProxyInstance(classLoader,interfaces,userHandler);proxyUser1.update('cicada') ;proxyUser2.update('smile') ; }}

這里之所以要生成代理類的結(jié)構(gòu)信息,因為從JVM加載的過程看不到相關(guān)內(nèi)容,關(guān)鍵信息再次被獨(dú)斷:

javap -v Proxy02.class

詳解Java的Proxy動態(tài)代理機(jī)制

查看代理類名稱

/* * proxyClassName=com.java.proxy.$Proxy0 */String proxyClassName = Proxy.newProxyInstance(classLoader,interfaces,userHandler).getClass().getName();System.out.println('proxyClassName='+proxyClassName);

下意識輸出代理對象名稱,這里即對應(yīng)JVM機(jī)制,找到Class對象名,然后分析結(jié)構(gòu),這樣就明白動態(tài)代理具體的執(zhí)行原理了。

生成代理類.class文件

System.getProperties().put('sun.misc.ProxyGenerator.saveGeneratedFiles', 'true');

通過上面JVM加載對象的機(jī)制可知,描述代理類的Class對象一定存在,只是在運(yùn)行時并沒有生成顯式的.class文件,通過上面生成代理類.class的語法,會在項目目錄的/com/java/proxy路徑下創(chuàng)建文件。

順便說一句:作為一只程序員,復(fù)雜總是和我們環(huán)環(huán)相繞,說好的簡單點呢?

4.3、代理類結(jié)構(gòu)

繼承與實現(xiàn)

class $Proxy0 extends Proxy implements IUser {}

從代理類的功能來思考,可以想到需要繼承Proxy與實現(xiàn)IUser接口,還有就是持有調(diào)用機(jī)制的具體實現(xiàn)類,用來做業(yè)務(wù)增強(qiáng)。

構(gòu)造方法

public $Proxy0(InvocationHandler var1) throws { super(var1);}

通過構(gòu)造方法,持有UserHandler具體的執(zhí)行機(jī)制對象。

接口實現(xiàn)

final class $Proxy0 extends Proxy implements IUser { private static Method m3; public final Integer update(String var1) throws {try { return (Integer)super.h.invoke(this, m3, new Object[]{var1});} catch (RuntimeException | Error var3) { throw var3;} catch (Throwable var4) { throw new UndeclaredThrowableException(var4);} }}

目標(biāo)類的基本需求update()方法,通過代理類進(jìn)行承接,并基于UserHandler實現(xiàn)具體的增強(qiáng)業(yè)務(wù)處理。

基礎(chǔ)方法

final class $Proxy0 extends Proxy implements IUser { private static Method m0; private static Method m1; private static Method m2; public $Proxy0(InvocationHandler var1) throws {super(var1); } static {try { m1 = Class.forName('java.lang.Object').getMethod('equals', Class.forName('java.lang.Object')); m2 = Class.forName('java.lang.Object').getMethod('toString'); m3 = Class.forName('com.java.proxy.IUser').getMethod('update', Class.forName('java.lang.String')); m0 = Class.forName('java.lang.Object').getMethod('hashCode');} catch (NoSuchMethodException var2) { throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) { throw new NoClassDefFoundError(var3.getMessage());} } public final boolean equals(Object var1) throws {try { return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) { throw var3;} catch (Throwable var4) { throw new UndeclaredThrowableException(var4);} } public final String toString() throws {try { return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) { throw var2;} catch (Throwable var3) { throw new UndeclaredThrowableException(var3);} } public final int hashCode() throws {try { return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) { throw var2;} catch (Throwable var3) { throw new UndeclaredThrowableException(var3);} }}

基于Object類,定義Java中幾個常用方法equals()判斷,toString()方法,hashCode()值,這個在分析Map源碼的時候有說過為什么這幾個方法通常都是一起出現(xiàn)。

4.4、JDK源碼

上面是案例執(zhí)行的過程和原理,還有一個關(guān)鍵點要明白,即JDK源碼的邏輯:

IUser proxyUser = (IUser) Proxy.newProxyInstance(classLoader,interfaces,userHandler);

Proxy提供的靜態(tài)方法newProxyInstance(),通過各個參數(shù)的傳入,構(gòu)建一個新的代理Class對象,即$Proxy0類的結(jié)構(gòu)信息,這里再回首看下三個核心參數(shù):

ClassLoader:基于JVM運(yùn)行過程,所以需要獲取目標(biāo)類UserService的類加載器; Interfaces:目標(biāo)類UserService實現(xiàn)的接口,從面向?qū)ο髞砜紤],接口與實現(xiàn)分離,代理類通過實現(xiàn)IUser接口,模擬目標(biāo)類的需求; InvocationHandler:代理類提供的功能封裝即UserHandler,可以在目標(biāo)方法調(diào)用前后做增強(qiáng)處理;

最后總結(jié)一下動態(tài)代理的實現(xiàn)的核心技術(shù)點:Jvm加載原理、反射機(jī)制、面向?qū)ο笏枷耄幻看伍喿xJDK的源碼都會驚嘆設(shè)計者的鬼斧神工,滴水穿石堅持才會有收獲。

五、源代碼地址

GitHub·地址

https://github.com/cicadasmile/java-base-parent

GitEE·地址

https://gitee.com/cicadasmile/java-base-parent

以上就是詳解Java的Proxy動態(tài)代理機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于Java Proxy 動態(tài)代理機(jī)制的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
丝袜a∨在线一区二区三区不卡| 男女性色大片免费观看一区二区 | 国产欧美日韩影院| 视频一区二区三区在线| 最新日韩av| 亚洲在线观看| 综合激情网...| 国产欧美一区| 色欧美自拍视频| 日韩欧美精品| 色婷婷精品视频| 蜜桃成人av| 午夜亚洲福利在线老司机| 黄色精品网站| 国产婷婷精品| 亚洲香蕉视频| 国产亚洲久久| 精品国产a一区二区三区v免费| 精品不卡一区| 婷婷国产精品| 视频一区视频二区中文| 日韩国产欧美一区二区三区| 欧美aⅴ一区二区三区视频| 91欧美国产| 欧美午夜不卡影院在线观看完整版免费| 日韩午夜精品| 国产精品最新自拍| 超碰超碰人人人人精品| 欧美色图国产精品| 亚洲精品成人一区| 美女精品一区二区| 一区二区三区视频免费观看 | 午夜影院欧美| 91精品福利观看| 日本一二区不卡| 欧美特黄一区| 国产精品伦一区二区| 国产99在线| 国产免费成人| 国产精品xxx| 亚洲一级高清| 日韩不卡一区二区| 国产+成+人+亚洲欧洲在线| 欧美a级一区| 青青伊人久久| 亚洲高清av| 欧美日韩亚洲三区| 久久国产小视频| 国产日韩中文在线中文字幕| 激情亚洲影院在线观看| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久亚州av| 午夜久久tv| 久久不见久久见中文字幕免费| 蜜臀国产一区| 四虎成人精品一区二区免费网站 | 成人免费电影网址| 日韩国产欧美视频| 国产在线欧美| 国产精品1区| 爽好多水快深点欧美视频| 精品久久久亚洲| 亚洲午夜国产成人| 日本久久成人网| 国产欧美日韩视频在线| 欧美日韩国产免费观看视频| 国产精品蜜月aⅴ在线| 欧美亚洲国产激情| 国产精成人品2018| 中文字幕亚洲精品乱码| 日韩不卡在线| 国产激情久久| 中文字幕亚洲影视| 在线日韩电影| 成人污污视频| 国产日韩欧美一区二区三区 | 国产探花一区| 国产免费成人| 日韩一区二区在线免费| 蜜臀av一区二区在线免费观看 | 欧美日韩一区二区三区不卡视频| 亚洲精品va| 国产精品高颜值在线观看| 日本久久一区| 亚洲尤物在线| 99精品国产一区二区三区| 国产精品视频首页| 亚洲精品免费观看| 午夜久久免费观看| 国产一区二区精品福利地址| 一区二区电影在线观看| 亚洲午夜精品久久久久久app| 精品一区二区三区中文字幕在线| 日韩一级网站| 伊人久久在线| 国产精品日本一区二区三区在线| 另类亚洲自拍| 精品在线91| 日韩高清不卡| 国产伊人久久| 国产精品免费精品自在线观看| 亚洲三级网站| 国产一区成人| 亚洲国产日韩欧美在线| av在线资源| 精品久久国产一区| 国产精品免费99久久久| 91欧美极品| 模特精品在线| 亚洲午夜精品久久久久久app| 成人在线黄色| 国产精品mv在线观看| 日韩精品一级| 亚洲精品伦理| 亚洲精品极品| 日韩欧美激情| 91精品国产经典在线观看| 日韩美女国产精品| 亚洲综合婷婷| 蜜臀av在线播放一区二区三区| 99久久久久久中文字幕一区| 国产在线视频欧美一区| 国产欧美综合一区二区三区| 麻豆精品网站| 尤物tv在线精品| 在线一区视频观看| 国产精品精品国产一区二区| 精品日韩在线| 久久久久伊人| 欧美激情精品| 久久97视频| 日韩88av| 欧美三区四区| 久久精品影视| 久久久人人人| 狠狠操综合网| 精品1区2区3区4区| 亚洲欧美日韩在线观看a三区| 亚洲激情欧美| 视频在线观看一区| 亚洲区欧美区| 久久精品av麻豆的观看方式| 久久激情五月婷婷| 国产一卡不卡| 9999国产精品| 免费观看久久av| 久久国产99| 日韩va欧美va亚洲va久久| 久久国产生活片100| 国产伦精品一区二区三区视频| 欧美激情网址| 日韩中文视频| 免费在线视频一区| 日韩三级一区| 卡一精品卡二卡三网站乱码| 国产一区二区三区免费在线| 日韩精品麻豆| 日韩中文字幕1| 国产亚洲久久| 91av亚洲| 国产视频一区三区| 日韩不卡免费视频| 国产一区二区三区免费在线| 亚洲一级影院| 日本免费新一区视频| 久久一区精品| 亚洲天堂黄色| 日韩精品导航| 久久午夜影院| 免费久久久久久久久| 天堂精品久久久久| 成人影视亚洲图片在线| 99国产精品久久久久久久成人热| 日韩影片在线观看| 日本久久综合| 蜜桃视频第一区免费观看| 国产精品一区二区av日韩在线| 欧美久久天堂| 日韩一区精品字幕| 国产精品一区毛片| 日韩精品久久久久久久电影99爱| 丝袜美腿高跟呻吟高潮一区| 国产精品白浆| 99免费精品| 欧美久久久网站| 激情五月综合网| 国产乱人伦丫前精品视频| 久久精品青草| 国产欧美日韩在线一区二区| 群体交乱之放荡娇妻一区二区| 亚洲+小说+欧美+激情+另类| 国产精品久久观看| 亚洲免费成人av在线| 国产一区二区三区日韩精品| 男女激情视频一区| 国产+成+人+亚洲欧洲在线| 久久av一区二区三区| 麻豆精品在线| 五月精品视频| 国产成人精品亚洲线观看|