<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java-JDK動(dòng)態(tài)代理(AOP)使用及實(shí)現(xiàn)原理分析

          共 15802字,需瀏覽 32分鐘

           ·

          2020-10-18 04:28

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          ? 作者?|??刺客伍六七

          來(lái)源 |? urlify.cn/Y3Mnae

          66套java從入門到精通實(shí)戰(zhàn)課程分享

          第一章:代理的介紹

          介紹:我們需要掌握的程度

          動(dòng)態(tài)代理(理解) 基于反射機(jī)制

          掌握的程度:

          1.什么是動(dòng)態(tài)代理?

          2.動(dòng)態(tài)代理能夠做什么?

          后面我們?cè)谟肧pirng和Mybatis的時(shí)候,要理解怎么使用的.

          1.什么是代理?

          代理,在我們?nèi)粘I钪芯陀畜w現(xiàn),代購(gòu),中介,換ip,商家等等.

          比如有一家美國(guó)的大學(xué),可以對(duì)全世界招生.留學(xué)中介(代理 )

          留學(xué)中介(代理):幫助這家美國(guó)的學(xué)校招生,中介是學(xué)校的代理中介是代替學(xué)校完成招生功能
          代理特點(diǎn)

          1. 中介和代理他們要做的事情是一致的:招生

          2. 中介是學(xué)校代理,學(xué)校是目標(biāo)

          3. 家長(zhǎng)-------->中介(學(xué)校介紹,辦理入學(xué)手續(xù))---------->美國(guó)學(xué)校

          4. 中介是代理,收取費(fèi)用

          2.為什么要找中介

          為什么要找中介?
          1.中介是專業(yè)的,方便.
          2.家長(zhǎng)現(xiàn)在不能自己去找學(xué)校。家長(zhǎng)沒(méi)有能力訪問(wèn)學(xué)校.或者美國(guó)學(xué)校不接收個(gè)人來(lái)訪

          買東西都是商家賣, 商家是某個(gè)商品的代理, 你個(gè)人買東西,肯定不會(huì)讓你接觸到廠家的.

          第二章:靜態(tài)代理

          2.1 使用代理模式的作用

          1. 功能增強(qiáng):在你原有的功能上,增加了額外的功能.新增加的功能,叫做功能增強(qiáng)

          2. 控制訪問(wèn):代理類不讓你訪問(wèn)目標(biāo),例如商家不讓用戶訪問(wèn)廠家

          2.2 實(shí)現(xiàn)代理的方式

          1.靜態(tài)代理:

          1)代理類是自己手工實(shí)現(xiàn)的,自己創(chuàng)建一個(gè)java類,表示代理類

          2)同時(shí)你所要代理的目標(biāo)

          特點(diǎn):1)實(shí)現(xiàn)簡(jiǎn)單2)容易理解。
          模擬一個(gè)用戶購(gòu)買u盤的行為。
          用戶是客戶端類
          商家:代理,代理某個(gè)品牌的u盤。
          廠家:目標(biāo)類。
          三者的關(guān)系:用戶(客戶端)-—-商家(代理)-—-廠家(目標(biāo))
          商家和廠家都是賣u盤的,他們完成的功能是一致的,都是賣u盤。

          實(shí)現(xiàn)步驟:

          實(shí)現(xiàn)步驟
          1.創(chuàng)建一個(gè)接口,定義賣u盤的方法,表示你的廠家和商家做的事情
          2.創(chuàng)建廠家類,實(shí)現(xiàn)1步驟的接口
          3.創(chuàng)建商家,就是代理,也需要實(shí)現(xiàn)1步驟中的接口
          4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個(gè)u盤

          2.3 具體實(shí)現(xiàn)

          實(shí)現(xiàn)步驟
          1.創(chuàng)建一個(gè)接口,定義賣u盤的方法,表示你的廠家和商家做的事情

          package?com.rango.service;
          public?interface?usbSell?{
          ????/**
          ?????*?定義一個(gè)方法?參數(shù)?amount:表示一次購(gòu)買的數(shù)量,暫時(shí)不用
          ?????*?返回值表示一個(gè)u盤的價(jià)格
          ?????*?@param?amount
          ?????*?@return
          ?????*/
          ????float?sell(int?amount);
          }

          2.創(chuàng)建廠家類,實(shí)現(xiàn)1步驟的接口

          package?com.rango.factory;

          import?com.rango.service.usbSell;
          //目標(biāo)類:金士頓廠家,不接受用戶的單獨(dú)購(gòu)買
          public?class?UsbKingFactory?implements?usbSell?{
          ????/**
          ?????*?定義一個(gè)方法?參數(shù)?amount:表示一次購(gòu)買的數(shù)量,暫時(shí)不用
          ?????*?返回值表示一個(gè)u盤的價(jià)格
          ?????*
          ?????*?@param?amount
          ?????*?@return
          ?????*/
          ????@Override
          //一個(gè)128G的U盤是85元.
          //????后期根據(jù)amount,可以實(shí)現(xiàn)不同的價(jià)格,例如10000個(gè),單擊是80,50000個(gè)75
          ????public?float?sell(int?amount)?{
          ????????return?85.0f*amount;
          ????}
          }

          3.創(chuàng)建商家,就是代理,也需要實(shí)現(xiàn)1步驟中的接口

          package?com.rango.business;

          import?com.rango.factory.UsbKingFactory;
          import?com.rango.service.usbSell;


          //淘寶是一個(gè)商家,代理金士頓U盤的銷售
          public?class?TaoBao?implements?usbSell?{
          //??????聲明?商家代理的廠家具體是誰(shuí)
          ????private?UsbKingFactory?factory?=new?UsbKingFactory();

          ????@Override
          //????實(shí)現(xiàn)銷售U盤功能
          ????public?float?sell(int?amount)?{
          //????????向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨
          //????????發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià)
          ????????float?price?=?factory.sell(amount);
          //????????商家需要加價(jià)也就是代理要增加價(jià)格
          ????????price?=?price?+?25;
          //在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強(qiáng)的意思
          ????????System.out.println("淘寶再給你返回一個(gè)優(yōu)惠券,或者紅包");
          //????????增加的價(jià)格
          ????????return?price;
          ????}
          }

          4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個(gè)u盤

          import?com.rango.business.TaoBao;

          public?class?shopMain?{
          ????public?static?void?main(String[]?args){
          //?????????????創(chuàng)建代理的商家淘寶對(duì)象
          ????????TaoBao?taoBao?=?new?TaoBao();
          //????????我只向淘寶買一件產(chǎn)品,得到報(bào)價(jià)
          ????????float?price?=?taoBao.sell(2);
          ????????System.out.println("購(gòu)買一件產(chǎn)品.淘寶的報(bào)價(jià)為:?"+price);
          ????}
          }


          所以我們?cè)俅慰偨Y(jié)代理類完成的功能:

          1. 目標(biāo)類中方法的調(diào)用

          2. 功能增強(qiáng)

          所屬我們只有一個(gè)代理商,我們實(shí)際上可以寫多個(gè)代理商,

          2.4 靜態(tài)代理的優(yōu)缺點(diǎn)

          我們?cè)俅慰偨Y(jié)一下靜態(tài)代理的優(yōu)缺點(diǎn)

          優(yōu)點(diǎn):

          1. 實(shí)現(xiàn)簡(jiǎn)單

          2. 容易簡(jiǎn)單

          確定:當(dāng)你的項(xiàng)目中,目標(biāo)類的代理類很多的時(shí)候,有一下的缺點(diǎn)

          1. 當(dāng)目標(biāo)類增加了,代理類可能也需要成倍的增加

          2. 當(dāng)你的接口中功能在增加了,或者修改了,會(huì)影響眾多的實(shí)現(xiàn)類,廠家類,代理都需要修改,影響比較多.

          所以我們繼續(xù)學(xué)習(xí)動(dòng)態(tài)代理

          第三章 動(dòng)態(tài)代理

          本章,我們所掌握的是

          1)什么是動(dòng)態(tài)代理?

          使用jdk的反射機(jī)制,創(chuàng)建對(duì)象的能力,創(chuàng)建的是代理類的的對(duì)象.而不用我們創(chuàng)建類文件,不用寫java文件,?什么叫動(dòng)態(tài)?在程序執(zhí)行時(shí),調(diào)用jdk提供的方法才能創(chuàng)建代理類的對(duì)象

          2)知道動(dòng)態(tài)代理能做什么?

          2.1 靜態(tài)代理和動(dòng)態(tài)代理模式的對(duì)比

          在靜態(tài)代理中目標(biāo)很多的時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)

          在靜態(tài)代理中目標(biāo)類很多時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)。
          動(dòng)態(tài)代理中目標(biāo)類即使很多,

          1. 代理類數(shù)量可以很少,

          2. 當(dāng)你修改了接口中的方法時(shí),不會(huì)影響代理類。

          動(dòng)態(tài)代理:在程序執(zhí)行過(guò)程中,使用jdk的反射機(jī)制,創(chuàng)建代理類對(duì)象,并動(dòng)態(tài)的指定要代理目標(biāo)類。
          換句話說(shuō):動(dòng)態(tài)代理是一種創(chuàng)建java象的能力,讓你不用創(chuàng)建 TaoBao類就能創(chuàng)建代理類對(duì)象,除去了中間商

          在java中,要想創(chuàng)建對(duì)象

          1. 創(chuàng)建類文件,java 文件編譯為class

          2. 使用構(gòu)造方法,創(chuàng)建類的對(duì)象

          2.1 動(dòng)態(tài)代理的介紹

          1. 動(dòng)態(tài)代理是指代理類對(duì)象在程序運(yùn)行時(shí)由JVM根據(jù)反射機(jī)制動(dòng)態(tài)生成的。動(dòng)態(tài)代理不需要定義代理類的,java源文件。

          2. 動(dòng)態(tài)代理其實(shí)就是jdk運(yùn)行期間,動(dòng)態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。

          3. 動(dòng)態(tài)代理的實(shí)現(xiàn)方式常用的有兩種:使用JDK代理,與通過(guò)CGLlB動(dòng)態(tài)代理。

          動(dòng)態(tài)代理的實(shí)現(xiàn):

          1. jdk動(dòng)態(tài)代理(理解):使用java反射包中的類和接口實(shí)現(xiàn)動(dòng)態(tài)代理的功能,反射包java.lang.reflect,里面有三個(gè)類:InvocationHandler,Method,Proxy

          2. cglib動(dòng)態(tài)代理(了解): cglib是第三方的工具庫(kù),創(chuàng)建代理對(duì)象

            1. cglib的原理是繼承,cglib通過(guò)繼承目標(biāo)類,創(chuàng)建它的子類,在子類中
              重寫父類中同名的方法,實(shí)現(xiàn)功能的修改。

            2. 因?yàn)閏glib是繼承,重寫方法,所以要求目標(biāo)類不能是fina1的,方法也不能是final的。cglib的要求目標(biāo)類比較寬松,只要能繼承就可以了。cglib在很多的框架中使用,
              比如mybatis,spring框架中都有使用。

          package?Test;

          import?com.rango.Impl.HelloServiceImpl;
          import?com.rango.service.HelloService;

          import?java.lang.reflect.InvocationTargetException;
          import?java.lang.reflect.Method;

          public?class?TestApp?{
          ????public?static?void?main(String[]?args)?throws?NoSuchMethodException,?InvocationTargetException,?IllegalAccessException?{
          //????????HelloService?service?=?new?HelloServiceImpl();
          //????????service.sayhello("張三");
          //????????以上是常規(guī)方法執(zhí)行sayhello
          //????????下面我們使用反射機(jī)制進(jìn)行創(chuàng)建sayhello方法,核心Method(類中的方法)
          ????????HelloServiceImpl?target?=?new?HelloServiceImpl();
          //????????獲取sayhello名稱對(duì)應(yīng)的Method類對(duì)象
          //?????????public?Method?getM???ethod(String?name,?Class...?parameterTypes)
          //????????加入,該方法的參數(shù)有多個(gè)該怎么辦?
          //??????? parameterTypes參數(shù)是一個(gè)類對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類型。
          ????????Method?method?=?HelloService.class.getMethod("sayhello",?String.class);
          //????????通過(guò)Metho可以執(zhí)行sayhello方法的調(diào)用
          ????????/*
          ????????*??public?Object?invoke(Object?obj,?Object...?args)
          ????????*???????表示執(zhí)行方法的調(diào)用
          ????????*???參數(shù):
          ????????*???????1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法
          ????????*???????2.Object...args,方法執(zhí)行時(shí)的參數(shù)值
          ????????*?返回值:
          ????????*???????Object:方法執(zhí)行后的返回值
          ????????*?*/
          ????????Object?ret?=?method.invoke(target,?"李四");
          ????}
          }

          2.2 回顧反射 Method類

          Method類的結(jié)構(gòu)圖

          • Class Method

            • java.lang.reflect.AccessibleObject

            • java.lang.reflect.Method

            • java.lang.reflect.Executable

            • java.lang.Object

          2.2.1 class.getMethod

          Method?method?=?HelloService.class.getMethod("sayhello",?String.class,Integer.class);

          提出問(wèn)題?

          ????public?Method?getMethod(String?name,?Class...?parameterTypes)

          加入,該方法的參數(shù)有多個(gè)該怎么辦?
          parameterTypes參數(shù)是一個(gè)類對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類型。

          2.2.2 Method.invoke

          public Object invoke(Object obj,Object... args)

          *??public?Object?invoke(Object?obj,?Object...?args)
          *???????表示執(zhí)行方法的調(diào)用
          *???參數(shù):
          *???????1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法
          *???????2.Object...args,方法執(zhí)行時(shí)的參數(shù)值
          *?返回值:
          *???????Object:方法執(zhí)行后的返回值
          *?

          2.3 JDK動(dòng)態(tài)代理

          實(shí)現(xiàn)步驟
          1.創(chuàng)建一個(gè)接口,定義賣u盤的方法,表示你的廠家和商家做的事情

          package?com.rango.service;
          public?interface?usbSell?{
          ????/**
          ?????*?定義一個(gè)方法?參數(shù)?amount:表示一次購(gòu)買的數(shù)量,暫時(shí)不用
          ?????*?返回值表示一個(gè)u盤的價(jià)格
          ?????*?@param?amount
          ?????*?@return
          ?????*/
          ????float?sell(int?amount);
          }


          2.創(chuàng)建廠家類,實(shí)現(xiàn)1步驟的接口

          package?com.rango.factory;

          import?com.rango.service.usbSell;
          //目標(biāo)類:金士頓廠家,不接受用戶的單獨(dú)購(gòu)買
          public?class?UsbKingFactory?implements?usbSell?{
          ????/**
          ?????*?定義一個(gè)方法?參數(shù)?amount:表示一次購(gòu)買的數(shù)量,暫時(shí)不用
          ?????*?返回值表示一個(gè)u盤的價(jià)格
          ?????*
          ?????*?@param?amount
          ?????*?@return
          ?????*/
          ????@Override
          //一個(gè)128G的U盤是85元.
          //????后期根據(jù)amount,可以實(shí)現(xiàn)不同的價(jià)格,例如10000個(gè),單擊是80,50000個(gè)75
          ????public?float?sell(int?amount)?{
          ????????return?85.0f*amount;
          ????}
          }


          3.創(chuàng)建商家,就是代理,也需要實(shí)現(xiàn)1步驟中的接口

          package?com.rango.business;

          import?com.rango.factory.UsbKingFactory;
          import?com.rango.service.usbSell;


          //淘寶是一個(gè)商家,代理金士頓U盤的銷售
          public?class?TaoBao?implements?usbSell?{
          //??????聲明?商家代理的廠家具體是誰(shuí)
          ????private?UsbKingFactory?factory?=new?UsbKingFactory();

          ????@Override
          //????實(shí)現(xiàn)銷售U盤功能
          ????public?float?sell(int?amount)?{
          //????????向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨
          //????????發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià)
          ????????float?price?=?factory.sell(amount);
          //????????商家需要加價(jià)也就是代理要增加價(jià)格
          ????????price?=?price?+?25;
          //在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強(qiáng)的意思
          ????????System.out.println("淘寶再給你返回一個(gè)優(yōu)惠券,或者紅包");
          //????????增加的價(jià)格
          ????????return?price;
          ????}
          }


          4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個(gè)u盤

          import?com.rango.business.TaoBao;

          public?class?shopMain?{
          ????public?static?void?main(String[]?args){
          //?????????????創(chuàng)建代理的商家淘寶對(duì)象
          ????????TaoBao?taoBao?=?new?TaoBao();
          //????????我只向淘寶買一件產(chǎn)品,得到報(bào)價(jià)
          ????????float?price?=?taoBao.sell(2);
          ????????System.out.println("購(gòu)買一件產(chǎn)品.淘寶的報(bào)價(jià)為:?"+price);
          ????}
          }



          所以我們?cè)俅慰偨Y(jié)代理類完成的功能:

          1. 目標(biāo)類中方法的調(diào)用

          2. 功能增強(qiáng)

          所屬我們只有一個(gè)代理商,我們實(shí)際上可以寫多個(gè)代理商,

          2.4 靜態(tài)代理的優(yōu)缺點(diǎn)

          我們?cè)俅慰偨Y(jié)一下靜態(tài)代理的優(yōu)缺點(diǎn)

          優(yōu)點(diǎn):

          1. 實(shí)現(xiàn)簡(jiǎn)單

          2. 容易簡(jiǎn)單

          確定:當(dāng)你的項(xiàng)目中,目標(biāo)類的代理類很多的時(shí)候,有一下的缺點(diǎn)

          1. 當(dāng)目標(biāo)類增加了,代理類可能也需要成倍的增加

          2. 當(dāng)你的接口中功能在增加了,或者修改了,會(huì)影響眾多的實(shí)現(xiàn)類,廠家類,代理都需要修改,影響比較多.

          所以我們繼續(xù)學(xué)習(xí)動(dòng)態(tài)代理

          第三章 動(dòng)態(tài)代理

          本章,我們所掌握的是

          1)什么是動(dòng)態(tài)代理?

          使用jdk的反射機(jī)制,創(chuàng)建對(duì)象的能力,創(chuàng)建的是代理類的的對(duì)象.而不用我們創(chuàng)建類文件,不用寫java文件,?什么叫動(dòng)態(tài)?在程序執(zhí)行時(shí),調(diào)用jdk提供的方法才能創(chuàng)建代理類的對(duì)象

          2)知道動(dòng)態(tài)代理能做什么?

          2.1 靜態(tài)代理和動(dòng)態(tài)代理模式的對(duì)比

          在靜態(tài)代理中目標(biāo)很多的時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)

          在靜態(tài)代理中目標(biāo)類很多時(shí)候,可以使用動(dòng)態(tài)代理,避免靜態(tài)代理的缺點(diǎn)。
          動(dòng)態(tài)代理中目標(biāo)類即使很多,

          1. 代理類數(shù)量可以很少,

          2. 當(dāng)你修改了接口中的方法時(shí),不會(huì)影響代理類。

          動(dòng)態(tài)代理:在程序執(zhí)行過(guò)程中,使用jdk的反射機(jī)制,創(chuàng)建代理類對(duì)象,并動(dòng)態(tài)的指定要代理目標(biāo)類。
          換句話說(shuō):動(dòng)態(tài)代理是一種創(chuàng)建java象的能力,讓你不用創(chuàng)建 TaoBao類就能創(chuàng)建代理類對(duì)象,除去了中間商

          在java中,要想創(chuàng)建對(duì)象

          1. 創(chuàng)建類文件,java 文件編譯為class

          2. 使用構(gòu)造方法,創(chuàng)建類的對(duì)象

          2.1 動(dòng)態(tài)代理的介紹

          1. 動(dòng)態(tài)代理是指代理類對(duì)象在程序運(yùn)行時(shí)由JVM根據(jù)反射機(jī)制動(dòng)態(tài)生成的。動(dòng)態(tài)代理不需要定義代理類的,java源文件。

          2. 動(dòng)態(tài)代理其實(shí)就是jdk運(yùn)行期間,動(dòng)態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。

          3. 動(dòng)態(tài)代理的實(shí)現(xiàn)方式常用的有兩種:使用JDK代理,與通過(guò)CGLlB動(dòng)態(tài)代理。

          動(dòng)態(tài)代理的實(shí)現(xiàn):

          1. jdk動(dòng)態(tài)代理(理解):使用java反射包中的類和接口實(shí)現(xiàn)動(dòng)態(tài)代理的功能,反射包java.lang.reflect,里面有三個(gè)類:InvocationHandler,Method,Proxy

          2. cglib動(dòng)態(tài)代理(了解): cglib是第三方的工具庫(kù),創(chuàng)建代理對(duì)象

            1. cglib的原理是繼承,cglib通過(guò)繼承目標(biāo)類,創(chuàng)建它的子類,在子類中
              重寫父類中同名的方法,實(shí)現(xiàn)功能的修改。

            2. 因?yàn)閏glib是繼承,重寫方法,所以要求目標(biāo)類不能是fina1的,方法也不能是final的。cglib的要求目標(biāo)類比較寬松,只要能繼承就可以了。cglib在很多的框架中使用,
              比如mybatis,spring框架中都有使用。

          package?Test;

          import?com.rango.Impl.HelloServiceImpl;
          import?com.rango.service.HelloService;

          import?java.lang.reflect.InvocationTargetException;
          import?java.lang.reflect.Method;

          public?class?TestApp?{
          ????public?static?void?main(String[]?args)?throws?NoSuchMethodException,?InvocationTargetException,?IllegalAccessException?{
          //????????HelloService?service?=?new?HelloServiceImpl();
          //????????service.sayhello("張三");
          //????????以上是常規(guī)方法執(zhí)行sayhello
          //????????下面我們使用反射機(jī)制進(jìn)行創(chuàng)建sayhello方法,核心Method(類中的方法)
          ????????HelloServiceImpl?target?=?new?HelloServiceImpl();
          //????????獲取sayhello名稱對(duì)應(yīng)的Method類對(duì)象
          //?????????public?Method?getM???ethod(String?name,?Class...?parameterTypes)
          //????????加入,該方法的參數(shù)有多個(gè)該怎么辦?
          //??????? parameterTypes參數(shù)是一個(gè)類對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類型。
          ????????Method?method?=?HelloService.class.getMethod("sayhello",?String.class);
          //????????通過(guò)Metho可以執(zhí)行sayhello方法的調(diào)用
          ????????/*
          ????????*??public?Object?invoke(Object?obj,?Object...?args)
          ????????*???????表示執(zhí)行方法的調(diào)用
          ????????*???參數(shù):
          ????????*???????1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法
          ????????*???????2.Object...args,方法執(zhí)行時(shí)的參數(shù)值
          ????????*?返回值:
          ????????*???????Object:方法執(zhí)行后的返回值
          ????????*?*/
          ????????Object?ret?=?method.invoke(target,?"李四");
          ????}
          }


          2.2 回顧反射 Method類

          Method類的結(jié)構(gòu)圖

          • Class Method

            • java.lang.reflect.AccessibleObject

            • java.lang.reflect.Method

            • java.lang.reflect.Executable

            • java.lang.Object

          2.2.1 class.getMethod

          Method?method?=?HelloService.class.getMethod("sayhello",?String.class,Integer.class);

          提出問(wèn)題?

          ????public?Method?getMethod(String?name,?Class...?parameterTypes)


          加入,該方法的參數(shù)有多個(gè)該怎么辦?
          parameterTypes參數(shù)是一個(gè)類對(duì)象數(shù)組,按聲明的順序標(biāo)識(shí)方法的形式參數(shù)類型。

          2.2.2 Method.invoke

          public Object invoke(Object obj,Object... args)

          *??public?Object?invoke(Object?obj,?Object...?args)
          *???????表示執(zhí)行方法的調(diào)用
          *???參數(shù):
          *???????1.Object,表示對(duì)象,要執(zhí)行這個(gè)對(duì)象的方法
          *???????2.Object...args,方法執(zhí)行時(shí)的參數(shù)值
          *?返回值:
          *???????Object:方法執(zhí)行后的返回值
          *?

          2.3 JDK動(dòng)態(tài)代理

          jdk動(dòng)態(tài)代理:
          1.反射, Method類,表示方法。類中的方法。通過(guò)Method可以執(zhí)行某個(gè)方法

          2.jdk動(dòng)態(tài)代理的實(shí)現(xiàn)
          反射包java.lang. reflect,里面有三個(gè)類:InvocationHandler,Method,Proxy

          2.3.1 Interface InvocationHandler

          public interface InvocationHandler

          InvocationHandler是由代理實(shí)例的調(diào)用處理程序?qū)崿F(xiàn)的接口 。
          每個(gè)代理實(shí)例都有一個(gè)關(guān)聯(lián)的調(diào)用處理程序。當(dāng)在代理實(shí)例上調(diào)用方法時(shí),方法調(diào)用將被編碼并分派到其調(diào)用處理程序的invoke方法。

          1)InvocationHandler接口(調(diào)用處理器):就一個(gè)方法 invoke()
          invoke():表示代理對(duì)象要執(zhí)行的功能代碼。你的代理類要完成的功能就寫在
          invoke()方法中。

          代理類完成的功能
          ????1.調(diào)用目標(biāo)方法,執(zhí)行目標(biāo)方法的功能
          ????2.功能增強(qiáng),在目標(biāo)方法調(diào)用時(shí),增加功能


          方法原型:

          參數(shù):object proxy:jdk創(chuàng)建的代理對(duì)象,無(wú)需賦值。
          ????????????????Method?method:目標(biāo)類中的方法,jdk提供method對(duì)象的
          ??????????????? object[]args:目標(biāo)類中方法的參數(shù),jdk提供的。

          Object?invoke(Object?proxy,方法?method,Object[]?args)throws?
          ????
          ??? Throwable處理代理實(shí)例上的方法調(diào)用并返回結(jié)果。



          2.3.2 Method

          2)Method類:表示方法的,確切的說(shuō)就是目標(biāo)類中的方法。
          作用:通過(guò) Method可以執(zhí)行某個(gè)目標(biāo)類的方法, Method. invoke();
          method. invoke(目標(biāo)對(duì)象,方法的參數(shù))

          object ret= method. invoke(service22,"李四")

          說(shuō)明:method.invoke()就是為了用來(lái)執(zhí)行目標(biāo)方法的,等同于靜態(tài)代理中的

          ???//????????向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨
          ????//????????發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià)
          ????????????float?price?=?factory.sell(amount);

          2.3.3 Proxy類

          3)proxy類:核心的對(duì)象,創(chuàng)建代理對(duì)象。之前創(chuàng)建對(duì)象都是new類的構(gòu)造方法()
          現(xiàn)在我們是使用proxy類的方法,代替new的使用。
          方法:靜態(tài)方法?
          newProxyInstance()
          作用是:創(chuàng)建代理對(duì)象,等同于靜態(tài)代理中的TaoBao taoBao=new TaoBao()

          我們來(lái)觀察方法原型

          ????public?static?Object?newProxyInstance(?ClassLoader?loader,Class[]?interfaces,InvocationHandler?h)???throws?IllegalArgumentException


          參數(shù):

          1. ClassLoader loader 類加載器,負(fù)責(zé)向內(nèi)存中加載對(duì)象的,使用反射機(jī)制獲取對(duì)象的classLoader,

          如何獲取? 類 a, a.getCalss().getClassLoader(),目標(biāo)對(duì)象的類加載器

          這里我們細(xì)分:每一個(gè)類都繼承Object類,在Object中有一個(gè)getClass方法,表示 類對(duì)象的運(yùn)行時(shí)類的Class對(duì)象。而Class類里面有一個(gè)public ClassLoader getClassLoader()方法

          1. Class[] interfaces: 接口,目標(biāo)對(duì)象實(shí)現(xiàn)的接口,也是反射獲取的

          2. InvocationHandler h : 我們自己寫的,代理類要完成的功能

          返回值也就是代理對(duì)象

          第四章 實(shí)現(xiàn)動(dòng)態(tài)代理的步驟

          1. 創(chuàng)建接口,定義目標(biāo)類要完成的功能

          2. 創(chuàng)建目標(biāo)類實(shí)現(xiàn)接口

          3. 創(chuàng)建InvocationHandler接口的實(shí)現(xiàn)類,在invoke方法中完成代理類的功能

            1. 調(diào)用目標(biāo)方法

            2. 增強(qiáng)功能

          4. 使用Proxy類的靜態(tài)方法,創(chuàng)建代理對(duì)象,并把返回值轉(zhuǎn)換成接口類型

          第一步:創(chuàng)建接口,定義目標(biāo)所需功能

          public?interface?UsbSell?{
          ????float?sell(int?amount);
          }


          第二步:創(chuàng)建目標(biāo)類實(shí)現(xiàn)接口

          public?class?UsbKingFactory?implements?UsbSell?{
          ????@Override
          ????public?float?sell(int?amount)?{
          ????????System.out.println("目標(biāo)類中,執(zhí)行了sell目標(biāo)方法");
          ????????return?85.02f;
          ????????
          ????}
          }


          我們寫了接口類,定義了功能,寫了代理類,實(shí)現(xiàn)了接口功能,按照以前的操作,現(xiàn)在就需要寫一個(gè)真正的代理類,創(chuàng)建對(duì)象.

          第三步: 創(chuàng)建Invocationhandler實(shí)現(xiàn)類.在invoke()方法中完成代理類的對(duì)象

          1.調(diào)用目標(biāo)的方法

          2.增強(qiáng)功能

          public?class?MyHandle?implements?InvocationHandler?{
          ????@Override
          ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{
          ????????return?null;
          ????}
          }



          我們就在以前代理類的實(shí)現(xiàn)方法上進(jìn)行修改

          //之前的代理類
          ??public?class?TaoBao?implements?usbSell?{
          ????//??????聲明?商家代理的廠家具體是誰(shuí)
          ????????private?UsbKingFactory?factory?=new?UsbKingFactory();

          ????????@Override
          ????//????實(shí)現(xiàn)銷售U盤功能
          ????????public?float?sell(int?amount)?{
          ????//????????向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨
          ????//????????發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià)
          ????????????float?price?=?factory.sell(amount);
          ????//????????商家需要加價(jià)也就是代理要增加價(jià)格
          ????????????price?=?price?+?25;
          ????//在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強(qiáng)的意思
          ????????????System.out.println("淘寶再給你返回一個(gè)優(yōu)惠券,或者紅包");
          ????//????????增加的價(jià)格
          ????????????return?price;
          ????????}
          ????}


          調(diào)用目標(biāo)的方法

          //傳入是誰(shuí)的對(duì)象,就給誰(shuí)創(chuàng)建代理
          ????public?MyHandle(Object?target)?{
          ????????this.target?=?target;
          ????}
          invoke里面的設(shè)置
          ????????????????Object?res?=null;
          ????????????//????????向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨
          ????????????//????????發(fā)送給工廠,我需要的訂單,返回報(bào)價(jià)
          //????????????float?price?=?factory.sell(amount);
          ????????????res?=?method.invoke(target,args);???????//待執(zhí)行目標(biāo)方法,執(zhí)行后返回值


          第四步: 使用Proxy類的靜態(tài)方法,創(chuàng)建代理對(duì)象,并把返回值轉(zhuǎn)換成接口類型

          創(chuàng)建一個(gè)MainShop類.

          public?class?MainShop?{
          ????public?static?void?main(String[]?args){?
          //????????????1.創(chuàng)建對(duì)象,使用Proxy
          //????????????2.創(chuàng)建目標(biāo)對(duì)象
          ????????UsbSell?factory?=?new?UsbKingFactory();
          //????????3.創(chuàng)建Invocationhandler對(duì)象
          ????????InvocationHandler?myHandle?=?new?MyHandle(factory);

          //????????4.創(chuàng)建代理對(duì)象
          ????????UsbSell?proxy?=?(UsbSell)?Proxy.newProxyInstance(factory.getClass().getClassLoader(),
          ????????????????factory.getClass().getInterfaces(),
          ????????????????myHandle);
          //????????通過(guò)代理執(zhí)行方法
          ????????float?price?=?proxy.sell(1);
          ????????System.out.println("通過(guò)動(dòng)態(tài)代理對(duì)象,調(diào)用方法:"?+price);
          ????}
          }



          執(zhí)行成功.和之前動(dòng)態(tài)代理模式一樣

          第五 JDK動(dòng)態(tài)代理執(zhí)行流程

          我們先復(fù)習(xí)一下,Proxy類,實(shí)現(xiàn)動(dòng)態(tài)代理的流程,使用返回指定接口的代理類實(shí)例,

          我們此時(shí)debug一下程序,在invok實(shí)現(xiàn)類中打一個(gè)斷點(diǎn)

          此時(shí)我們?cè)儆^察,代理對(duì)象MyHandler里面的invoke方法的參數(shù)

          第六章 靜態(tài)代理項(xiàng)目中的應(yīng)用

          我們需要知道代理能做什么?

          在不改變?cè)瓉?lái)目標(biāo)方法功能的前提下,可以在代理中增強(qiáng)自己的功能代碼,程序開發(fā)中的意思,

          比如:你所在的項(xiàng)目,有一個(gè)功能是其他人(公司其他部門,其他小組的人)寫好的,你可以使用

          //比如,同事開發(fā)一個(gè)GoNong類
          GoNong.class?,
          GoNong?gn=new?GoNong()
          ????//我們需要增加一個(gè)print方法


          我們發(fā)現(xiàn)這個(gè)功能現(xiàn)在還存在缺點(diǎn),不能完全滿足我項(xiàng)目的需要,我需要在print()執(zhí)行過(guò)后,需要自己再增加代理,使用什么方法那,肯定是代理,因?yàn)閯e人不會(huì)讓我們看源文件

          執(zhí)行步驟:

          1. 我們先建立一個(gè)接口功能,很簡(jiǎn)單的一個(gè)功能

          public?interface?HelloService?{
          ????/**
          ?????*?打印報(bào)表,報(bào)表
          ?????*?@param?name
          ?????*?@return
          ?????*/
          ????int?print?(String?name);
          }




          1. 我們?cè)偌觽€(gè)接口實(shí)現(xiàn)類


          public?class?GoNeng?implements?HelloService?{
          ????@Override
          ????public?int?print(String?name)?{
          ????????System.out.println("其他人寫好的這個(gè)方法!");
          ????????return?2;
          ????}
          }

          1. 我們?nèi)绻鄬?duì)上述功能進(jìn)行修改,我們不可能直接去在原方法上進(jìn)行修改

          我們?cè)O(shè)置一個(gè)類來(lái)使用這個(gè)接口

          public?class?MyApp?{
          ????public?static?void?main(String[]?args){
          ????????GoNeng?gn?=?new?GoNeng();
          ????????int?i?=?gn.print("nihao1");
          ????????System.out.println("num"?+i);

          ????}
          }



          問(wèn)題是如果我們想修改這個(gè)功能改怎么辦?在不修改源代碼的基礎(chǔ)上,我們可以創(chuàng)建一個(gè)代理類,來(lái)增強(qiáng)這個(gè)類方法,

          1. 設(shè)置一個(gè)代理類實(shí)現(xiàn)功能的增強(qiáng)和代理

          public?class?MyInvocationHandler?implements?InvocationHandler?{
          ????private?Object?target=null;

          ????public?MyInvocationHandler(Object?target)?{
          ????????this.target?=?target;
          ????}

          ????@Override
          ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{
          //????????調(diào)用目標(biāo)方法,執(zhí)行print()得到2
          ?????Object?res??=??method.invoke(target,args);??//返回為2的結(jié)果
          ????????//我們可以把結(jié)果再乘以2
          ????????if?(res!=null)
          ????????{
          ????????????Integer?num??=?(Integer)?res;
          ????????????res?=?num*2;?
          ????????}

          ????????????return?null;
          ????}
          }

          1. 我們?nèi)曰氐街鞣椒ɡ锩孢M(jìn)行測(cè)試

          public?class?MyApp?{
          ????public?static?void?main(String[]?args){
          //????????GoNeng?gn?=?new?GoNeng();
          //????????int?i?=?gn.print("nihao1");
          //????????System.out.println("num"?+i);
          ????????GoNeng?goNeng?=?new?GoNeng();
          ????????InvocationHandler?handler?=?new?MyInvocationHandler(goNeng);
          ????????HelloService?proxy?=?(HelloService)?Proxy.newProxyInstance(goNeng.getClass().getClassLoader(),?goNeng.getClass().getInterfaces(),
          ????????????????handler);
          ????????int?num?=?proxy.print("市場(chǎng)");
          ????????System.out.println("我們期望得到的?num?=="+num);
          ????}
          }

          測(cè)試System.out.println("動(dòng)態(tài)代理類參數(shù)接口"+goNeng.getClass().getInterfaces()[0].getName());

          動(dòng)態(tài)代理類參數(shù)接口com.rango.service.HelloService
          其他人寫好的這個(gè)方法!
          我們期望得到的?num?==4

          完結(jié)

          動(dòng)態(tài)代理,必須要有接口出現(xiàn),如果沒(méi)有,我們可以使用cglib實(shí)現(xiàn)






          ??? ?



          感謝點(diǎn)贊支持下哈?

          瀏覽 35
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费一区二区三区四区 | 国产又粗又大又爽 | 欧美日笔视频 | 俺去俺来也在线WWW色官方 | 亚洲天堂无码在线观看 |