日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态代理 ---- 框架基础技术

發布時間:2024/3/7 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态代理 ---- 框架基础技术 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JSK動態代理

內容導航

  • 代理模式 proxy pattern
    • proxy
    • proxy pattern
    • proxy role
    • 靜態代理 static proxy
      • 靜態代理的缺點
    • dynamic proxy 動態代理
      • 反射 -- Method
      • 動態代理步驟
      • 動態代理實例

Javaweb — 深化一下反射,之后會再看一下線程和并發


java設計模式 — 代理模式: 動態代理jdk實現


JQuery雖然被新的技術取代了,但是通過實例就發現相比原生的JS,JQuery簡化了很多;接下來再來看看動態代理— 其實就是之前的反射機制,J2EE中使用過多次了,這里正式來康康

動態代理 — 基于反射機制的;之前使用過多次反射,尤其是幾個工具類,第一個就是DBUtil使用了簡單的forname方式進行類加載;之后再JSONUtil中使用了Class和Field;和方法一樣設置可以access變可獲取私有的屬性,正常的情況下是獲取不到的

代理模式 proxy pattern

proxy

代理就比如中介一樣,幫助去實現某些操作,也就是允許客戶端通過這個服務與另外一個end system進行非直接的服務,所以說路由器等就相當于是一個代理

從中介來分析: 比如房產中介,中介和代理所做的事情都是一致的,那就是招攬客人; 中介是房源的代理,房源是目標;這個過程就是 【客戶 -----> 中介 ------> 房源】,中介是代理,會收費的;盡管如此,還是有很多中介存在;因為中介是專業的、非常的方便;其次就是客戶不能獨自找到房源,或者找房源十分困難

在實際開發中,也就有了代理的情況,也就是對客戶----代理 ---- 目標鏈式關系的抽象,比如有一個類A,還有一個類C,如果A類的功能需要調用C類,但是C類不允許A調用,所以這個時候可以找一個代理類B,B訪問C;A再訪問B即可,完成功能 【比如項目的短信驗證碼的功能,項目是不可能直接發送短信的,短信只有電信運營商才能發送,所以找一個中介關聯公司 項目 ------------- 關聯公司、中介 ------ 中國移動、電信、聯通】

proxy pattern

為其他對象提供一種代理可以控制對這個對象的訪問,在某些情況下,一個對象不舍和或者不能直接引用另一個對象,而代理對象可以在客戶類和目標對象之間起到中介的作用。使用代理模式,是為了在不修改目標對象的基礎上,增強業務邏輯,客戶類對目標對象的訪問時通過訪問代理對象來實現

proxy role

上面介紹了代理模式,那么其作用是什么呢?

  • 功能增強、易于擴展 --------- 原來比如new Dao(),那么如果使用代理類來執行這個操作,在代理類中所寫的其他的代碼就是屬于功能增強;但是這并沒有修改原來的代碼【符合開閉原則】
  • 控制訪問,保護對象 ------ 目標類不讓客戶類直接訪問,這樣可以對目標類起到保護的作用
  • 使職責更加明確 ----- 比如在service中應該全部都是業務邏輯,而創建對象不屬于業務邏輯,使用代理可以明確分工
  • 代理模式分為靜態代理和動態代理,二者的不同?

    靜態代理 static proxy

  • 代理類是自己手工實現,自己創建一個java類,來表示代理類
  • 代理的目標類是確定的
  • 實現很簡單,容易理解
  • 這里來做一個例子來模擬一下代理,比如現在抽象一個關系鏈條 : 用戶到商家位置買雪糕; 商家的雪糕從廠家進的;現在用戶想要購買雪糕,實現功能【不能直接從廠家拿雪糕】,那么實現這個功能: 首先需要創建一個接口,定義賣雪糕的方法,展示商家和廠家的做的事情;其次創建廠家和商家類都要實現接口,最后創建客戶類,調用商家的方法買一個雪糕

    通過代理模式才能進行功能增強,也就是擴展功能;對擴展開發,對修改關閉

    package cfeng.proxy;//表示功能,廠家和商家都要實現這個方法 public interface IcecreamSell {//定義方法,售賣雪糕param表示單價float sell(int amount);//可以定義其他的方法 }

    這里就是接口,商家和廠家都會實現這個接口

    package cfeng.proxy;public class CfengFactory implements IcecreamSell { //廠家不支持用戶的單獨購買@Overridepublic float sell(int amount) {//簡單return即可return 85.0f;}}

    廠家繼承了接口,對接口進行了繼承,完成了雪糕的銷售

    package cfeng.proxy;public class Merchant implements IcecreamSell {//聲明商家所代理的生產雪糕廠家private IcecreamSell factory = new CfengFactory();@Overridepublic float sell(int amount) {//向廠家調用訂單,告訴廠家,讓其發貨float pri = factory.sell(amount);//商家作為中間商需要加價pri += 25; //這部分代碼就是屬于功能增強,因為原來只會有上面的代碼,這里都是額外的,易于擴展//返回給用戶價格return pri;} }

    商家也實現了接口,這里商家完成了兩件事情,第一件事情就是調用廠家的方法,第二件事就是進行加價;加價這部分【除了原來的方法的調用之外】,都是屬于功能的增強的部分

    package cfeng.proxy;public class Client {//從商家購買雪糕;不能直接從public static void main(String[] args) {Merchant mercha = new Merchant();System.out.println(mercha.sell(1));} }

    最后就是客戶類,客戶通過調用商家【代理】的【增強之后的】方法,完成了業務;這里的代理可以有多個,因為可以有多個商家,它們所做的處理不同;所以不同的代理可以完成不同的擴展

    因此: 代理的最主要的功能就是 : 目標類的方法的調用【代理是沒有直接的目標的功能的】, 功能的增強

    靜態代理的缺點

    • 靜態代理的目標固定,所以如果有很多目標,那就需要很多個代理,這樣代碼冗雜了

    • 當接口中功能增加了,或者修改了,因為眾多的代理實現類,那么修改的工作量大,這樣就容易出現問題

    dynamic proxy 動態代理

    在程序的執行過程中,創建代理對象,動態指定代理目標類;動態代理就是一種創建對象能力,不用創建類,就可以獲得對象 ------ 就是反射機制,獲得類的字節碼,再invoke即可; 動態代理是指代理類對象在程序運行時有JVM根據根舍機制動態生成的,動態代理不需要定義代理類的java源文件,動態獲取類,(比如通過對象,通過完整的類名) 動態創建class字節碼加載到JVM

    動態代理的方式:

    • JDK 動態代理: 使用java反射包中的類和接口實現動態代理的功能 反射包java.lang.reflect : 其中的三個類Method,InvocationHandler、Proxy
    • cglib動態代理 : cglib時第三方工具庫,創建代理對象,cglib的原理就是繼承,通過繼承目標類,創建其子類,在子類中重寫超類的方法,實現功能的修改 — 所以父類不能是final的;cglib在很多框架中使用【比如mybatis、springAOP就會使用

    反射 – Method

    之前分享反射的時候著重分享了幾個類,首先就是Class類,承載的是類的字節碼;之后還有Method類表示的是類中的方法【公私均可】,Field類表示的是類的屬性【公私均可】; 但是私有的一定要設置可訪問,setAccess;這是之前最經常使用的

    這里可以用反射的方式實現之前的客戶類

    public class Client {//從商家購買雪糕;不能直接從public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {/*Merchant mercha = new Merchant();System.out.println(mercha.sell(1));*///這里不通過創建對象的方式,如何得到上面的結果?反射即可 --- 使用Method//獲取類的字節碼 try {Class cls = Class.forName("cfeng.proxy.Merchant");//通過字節碼創建一個對象;通過構造方法創建Object obj = cls.getDeclaredConstructor().newInstance();//通過類的字節碼獲取到所有的方法Method method = cls.getDeclaredMethod("sell",int.class);//執行該方法通過method的invoke方法;第一個參數是對象,第二個是方法執行時的參數值 方法執行后的返回值Object o = method.invoke(obj, 1);//o就是函數的返回值System.out.println(o);} catch (ClassNotFoundException e) {e.printStackTrace();}} }
    • 這里通過類的字節碼創建對象,不能直接使用newInstance了,since version 9就過時了,需要先獲得構造器,之后再創建對象;
    • 獲得類的方法可以通過Class的getDeclaredMethod方法,第一個參數時方法的名稱,第二個參數是方法的參數的字節碼;
    • 執行方法通過Method的invoke方法,這個方法的第一個參數為該類的一個具體的對象,第二個參數是該方法傳入的具體的參數的值;返回值為方法的返回值【invoke 調用】

    動態代理步驟

    動態代理的目標不是固定的,根據代理的對象,動態創建代理類,這樣就避免了靜態代理中的類過多的問題,動態代理的實現方式---- 反射; 可以直接使用java.lang.reflect.Proxy; 動態代理的實現步驟如下

    jdk動態代理要求目標對象必須要實現接口,沒有接口就實現不了動態代理

  • 編寫一個委托類、目標類的接口【定義目標類要完成的功能】
  • 實現一個真正的委托類【編寫目標類】
  • 創建InvocationHandler接口的實現類,重寫invoke方法,完成代理類的功能—調用目標方法、增強功能
  • 使用Proxy類的newProxyInstance()靜態方法生成動態代理的對象 ,并將返回值轉為接口類型
  • 動態代理主要依托的reflect包中的三個類: invocationHandler、Method、Proxy

    • invocationHandler【調用處理器】 接口 ------- 就是表明代理要做什么: 這是一個函數式接口,其中就一個方法invoke;invoke方法表示代理對象要執行的功能代碼;代理類要完成的功能就卸載invoke代碼中【目標方法的調用、功能增強】
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable; Object proxy : 這是jdk創建的代理對象,無需賦值 Method method : 目標類中的方法,jdk提供method ---->這里的method代指的就是目標方法 Object[] args : 目標類中方法的參數 -----> 所以說如果有多個參數,就寫成一個集合即可 --->目標方法的參數 {int.class,String.class,……}
    • Method類: 表示方法的,也就是通過Method可以執行某個目標類的方法,通過invoke方法執行目標的方法

    • Proxy類: 核心的對象,用于創建代理對象,之前創建對象都是new 類構造方法;現在可以直接使用Proxy類的方法,代替new的使用

    靜態方法 ---- newProxyInstance()方法 作用就是創建代理對象,等同于靜態代理的new ……

    這里可以看一下源碼

    @CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) {Objects.requireNonNull(h);final Class<?> caller = System.getSecurityManager() == null? null: Reflection.getCallerClass();Constructor<?> cons = getProxyConstructor(caller, loader, interfaces);return newProxyInstance(caller, cons, h);}ClassLoader loader : 類加載器,負責向內存中加載對象 --- 使用反射機制就可以獲得對象的classLoader ----比如對于類String ---String.class.getClassLoader() 也就是獲得目標的類Class<?>[] interfaces 接口,目標對象實現的接口,也是通過反射獲取的InvocationHandler h :也就是之前實現的InvocationHandler接口,完成代理類的功能

    通過Proxy類的這個newProxyInstance方法就可以生成一個目標對象的代理對象

    動態代理實例

    這里就不另外編寫例子了,就以剛剛靜態代理的買雪糕的例子 ---- 用戶不能直接從從某一個具體的工廠買雪糕,那么就需要創建一個代理類商家來進行間接購買,同時商家增強了功能【抬價】 所以這里的核心應該是用戶和目標;商家是為了處理這個業務應運而生的類型

    按照動態代理的固定步驟,首先要規范目標類【服務類】的行為,面向接口編程,定義一個接口 ----- 定義接口的目的就是因為,客戶類想使用的其實就是該接口定義的方法,所以真正要代理的是方法,而不是某一個具體實現類;多態的核心就是抽象,這樣就便于擴展而少修改

    package cfeng.proxy;//表示功能,廠家和商家都要實現這個方法 public interface IcecreamSell {//定義方法,售賣雪糕param表示單價float sell(int amount);//可以定義其他的方法 }

    這個接口也就是為了完成客戶類想要實現的功能;之后定義實現類來實現這個功能接口

    package cfeng.proxy;public class CfengFactory implements IcecreamSell { //廠家不支持用戶的單獨購買@Overridepublic float sell(int amount) {//簡單return即可System.out.println("執行服務接口的具體實現類的實現方法");return 85.0f;}}

    本來按照靜態代理,接下來就要手動去創建針對這個服務類的代理類;但是動態代理接下來就是創建InvocationHandler接口的實現類

    這里的參數中,method就代表的是目標方法,args代表的就是目標方法的參數,所以為了執行方法,這里需要執行Method的invoke方法,需要傳入目標類型的對象,這里就使用帶有參數的構造方法實現傳入目標對象

    package cfeng.proxy;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** 完成代理類要執行的功能,這里需要注意的是后兩個對象就是目標參數,其實就是接口中的方法---代理方法而不是代理具體的實現類* 通過構造器獲得方法執行的具體的對象【多態】*/ public class SellHandler implements InvocationHandler {// sell功能的處理器【代理功能】private Object obj;public SellHandler(Object obj) {super();this.obj = obj;}// 完成代理類執行的功能@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null; //目標方法的返回值// 執行目標方法result = method.invoke(obj, args);//進行功能增強if(result != null) {float pri = (float)result;pri += 25;result = pri;}System.out.println("你獲得2元優惠");return result;} }

    第四步就是利用Proxy類的靜態方法生成代理對象;代理對象的目的也是執行接口中的sell方法,所以類型是接口的類型

    package cfeng.proxy;import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy;public class Client {//從商家購買雪糕;不能直接從public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {//創建需要代理的目標對象IcecreamSell fact = new CfengFactory();//創建調用處理器對象InvocationHandler handler = new SellHandler(fact);//創建代理對象 ---- obj.getClass 類.class Class.forName()IcecreamSell proxy = (IcecreamSell)Proxy.newProxyInstance(fact.getClass().getClassLoader(), fact.getClass().getInterfaces() , handler);//通過代理對象執行方法Object o = proxy.sell(1);System.out.println(o);} }單從這里來看,這里的動態代理就是類似于一種別樣的重載,比如sell;給出的代理類還是有接口中的方法;JDK的動態代理必須有接口,Proxy的第二個參數就一定是接口執行服務接口的具體實現類的實現方法 執行目標接口實現類的功能方法 你獲得2元優惠 執行代理對象的功能增強代碼 110.0 執行代理對象的功能增強代碼

    只能說動態代理和JDBC一樣固化,非常明確的幾個步驟

    首先就是編寫功能接口,【多態】實現接口;

    之后就是實現invocationHandler接口來封裝代理的功能 — 調用原方法、功能增強 ---- 最后就是使用Proxy的靜態方法生成代理對象;這個代理對象就是最開始定義的接口類型的;它的目的還是有這個sell功能 ----- 代理可以在不改變原有的功能的前提下,增加新的功能; 代理類和接口實現類都是接口類型的🎄

    總結

    以上是生活随笔為你收集整理的动态代理 ---- 框架基础技术的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 在线天堂视频 | 女性高潮视频 | 一级激情片 | 在线观看国产日韩 | 超碰三级 | www.亚洲色图 | 黑丝av在线 | 深夜网站在线观看 | 一级网站在线观看 | 日韩免费电影一区 | 中年夫妇啪啪高潮 | 999xxxxx | 三级视频在线 | 性欧美18一19内谢 | 国产精品永久免费 | 先锋影音av资源网站 | 欧美用舌头去添高潮 | 懂色av一区二区三区蜜臀 | 毛片网站在线播放 | 青青草老司机 | 在线免费黄 | 日本精品一区二区视频 | 中文在线日韩 | 国产女主播喷水视频在线观看 | 极品国产在线 | 亚洲伦理在线 | 超碰免费在线播放 | 大黄一级片 | 亚洲成人精品av | 自拍偷拍亚洲欧美 | 成人人伦一区二区三区 | 熟女俱乐部五十路六十路av | 欧美激情自拍 | 爱情岛论语亚洲入口 | 日韩免费在线观看视频 | 日韩欧美亚洲国产 | 情侣黄网站免费看 | 日本电影成人 | 天堂久久久久 | 青青草原成人网 | 永久免费的网站入口 | 国产精品婷婷午夜在线观看 | 国产伦精品一区二区三区网站 | 国产精品二区一区二区aⅴ 一卡二卡三卡在线观看 | 久久不卡av | 久草视频在线资源 | 久久这里有精品 | 在线精品视频免费观看 | 超碰在线观看97 | 日本一区高清 | 中文字幕亚洲欧美 | 天天操天天干天天爽 | 久草视频在线播放 | 污污小说在线观看 | 黄色777| 韩国妻子的朋友 | 草视频在线 | 激情婷婷丁香 | 久久国产加勒比精品无码 | 青青草55| 神马午夜影院 | 婷婷激情五月综合 | 99毛片| 国产一区不卡在线 | 日本黄色大片免费 | 五月天色婷婷综合 | 日本午夜一区二区 | 色综合99久久久无码国产精品 | 国产白浆一区二区 | 国产日韩亚洲欧美 | 懂色av成人一区二区三区 | 美女av免费| 亚洲AV成人无码久久精品同性 | 三年中国片在线高清观看 | 少妇被又大又粗又爽毛片久久黑人 | 国产午夜无码精品免费看奶水 | 欧美精品小视频 | 四虎精品| 中国黄色录像一级片 | 麻豆精品国产传媒av绿帽社 | 老色鬼网站 | 久久夜色网| 久久av秘一区二区三区 | 91色交视频 | www,99 | 欧美做受高潮动漫 | 欧洲午夜视频 | 北条麻妃99精品青青久久 | 欧美人妻一区二区 | 综合在线视频 | 男女一级片 | 夜色88v精品国产亚洲 | 91精品啪在线观看国产 | 很黄很污的视频网站 | 色呦呦在线免费观看 | 伊人久久大 | 午夜一级大片 | 亚洲免费影视 | 国产巨乳在线观看 |