最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java代理模式與動(dòng)態(tài)代理之間的關(guān)系以及概念

 更新時(shí)間:2023年02月20日 15:16:26   作者:綠仔牛奶_  
代理模式是開發(fā)中常見的一種設(shè)計(jì)模式,使用代理模式可以很好的對(duì)程序進(jìn)行橫向擴(kuò)展。動(dòng)態(tài)代理:代理類在程序運(yùn)行時(shí)被創(chuàng)建的代理方式。關(guān)鍵在于動(dòng)態(tài),程序具有了動(dòng)態(tài)特性,可以在運(yùn)行期間根據(jù)不同的目標(biāo)對(duì)象生成動(dòng)態(tài)代理對(duì)象

什么是代理模式

代理模式是開發(fā)中常見的一種設(shè)計(jì)模式,使用代理模式可以很好的對(duì)程序進(jìn)行橫向擴(kuò)展。代理,顧名思義就是一個(gè)真實(shí)對(duì)象會(huì)存在一個(gè)代理對(duì)象,并且代理對(duì)象可以替真實(shí)對(duì)象完成相應(yīng)操作,外部通過代理對(duì)象來訪問真實(shí)對(duì)象并且還可以在代理對(duì)象中進(jìn)行額外操作的擴(kuò)展。

代理模式的特征是擁有接口、代理類、被代理類。并且代理類與被代理類同時(shí)實(shí)現(xiàn)該接口。代理類與被代理類之間通常存在一定關(guān)聯(lián),設(shè)計(jì)時(shí)會(huì)在代理類中注冊(cè)一個(gè)被代理類的對(duì)象用于調(diào)用代理類的方法。這也印證了代理對(duì)象依然是執(zhí)行的真實(shí)對(duì)象的方法

代理模式又分為靜態(tài)代理和動(dòng)態(tài)代理

靜態(tài)代理

靜態(tài)代理,關(guān)鍵字靜態(tài)是指在程序運(yùn)行之前編譯時(shí)就已經(jīng)確定了代理類、被代理類、接口。

下面列舉兩個(gè)示例展示靜態(tài)代理:

學(xué)生通過班長(zhǎng)交班費(fèi),班長(zhǎng)作為學(xué)生的代理,學(xué)生是被代理,具有同一行為就是交班費(fèi),這個(gè)行為我們用接口進(jìn)行約束

程序:

// 接口
public interface Person {void giveMoney();}
// 學(xué)生類--> 被代理類
public class Student implements Person{
  private String name;
  public Student(String name) {this.name = name;}
  public void giveMoney() {
    System.out.println(name+"同學(xué)上交50元班費(fèi)");
  }
}
// 學(xué)生代理類
public class StuProxy implements Person{
  private Student stu;
  public StuProxy(Student stu) {
    if (stu.getClass() == Student.class) {
      this.stu = stu;
    }
  }
  public void giveMoney() {stu.giveMoney();}
}

測(cè)試:

public static void main(String[] args) {
  // 獲取學(xué)生實(shí)例  
  Student stu = new Student("張三");
  // 學(xué)生找交錢給班長(zhǎng)  學(xué)生找到代理
  StuProxy stuProxy = new StuProxy(stu);
  // 班長(zhǎng)交給老師  代理交錢(交的是學(xué)生的錢)
  stuProxy.giveMoney();
}

房屋租賃,租客通過中介找房源,租客為被代理類,中介為代理類,接口聲明租房方法

// 接口
public interface Rent {void doRent();}
// 被代理類
public class Renter implements Rent{
  public void doRent() {
    System.out.println("租客租房了");
  }
}
// 代理類
public class RentProxy implements Rent{
  private Renter renter;
  public RentProxy(Renter renter) {
    if (renter.getClass()==Renter.class)
      this.renter = renter;
  }
  public void doRent() {renter.doRent();}
}

測(cè)試:

public static void main(String[] args) {
  // 創(chuàng)建租客
  Renter renter = new Renter();
  // 租客找到中介
  RentProxy rentProxy = new RentProxy(renter);
  // 租客租房
  rentProxy.doRent();
}

上述兩個(gè)示例,向代理類中注入被代理對(duì)象的方式都是通過構(gòu)造器注入,當(dāng)然也可以通過set方法注入

下面演示如果需要在已經(jīng)編寫好的代理類的輸出中添加其他操作時(shí)的操作比如打印一個(gè)日志,在不修改源代碼的情況下擴(kuò)展

// 下面是最經(jīng)典的Service層的寫法
public interface UserService {
    void del();
    void select();
}
public class UserServiceImpl implements UserService{
    public void del() {
        System.out.println("刪除操作");
    }
    public void select() {
        System.out.println("查詢操作");
    }
}

假設(shè)現(xiàn)在我們需要在每一次執(zhí)行操作前后打印一次執(zhí)行日志,并且不能修改源代碼那么就可以用到代理模式,將UserServiceImpl作為被代理類,擴(kuò)展代理類如下:

public class UserServiceImplProxy implements UserService{
  private UserServiceImpl userService;
  // set注入
  public void setUserService(UserServiceImpl userService) {
    this.userService = userService;
  }
  public void del() {
    printLog();
    userService.del();
  }
  public void select() {
    printLog();
    userService.select();
  }
  private void printLog(){
    System.out.println("執(zhí)行時(shí)間="+new Date());
  }
}

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

動(dòng)態(tài)代理:代理類在程序運(yùn)行時(shí)被創(chuàng)建的代理方式。

關(guān)鍵在于動(dòng)態(tài),程序具有了動(dòng)態(tài)特性,可以在運(yùn)行期間根據(jù)不同的目標(biāo)對(duì)象生成動(dòng)態(tài)代理對(duì)象,并且可以通過動(dòng)態(tài)代理對(duì)象對(duì)目標(biāo)對(duì)象(真實(shí)對(duì)象)進(jìn)行功能性補(bǔ)強(qiáng)。大白話來講就是,可以在程序運(yùn)行期間額外的對(duì)真實(shí)對(duì)象功能進(jìn)行擴(kuò)展。

此處的動(dòng)態(tài)代理對(duì)象不是通過預(yù)先編寫好的程序生成的,而是運(yùn)行期間由于用戶需求或者說是代碼的指示生成的

動(dòng)態(tài)代理分為兩種:一類是基于接口實(shí)現(xiàn)的動(dòng)態(tài)代理,另一類是基于類的動(dòng)態(tài)代理

基于接口的動(dòng)態(tài)代理–JDK動(dòng)態(tài)代理通過反射完成,基于類實(shí)現(xiàn)的–>cglib

JDK動(dòng)態(tài)代理核心:Proxy類、InvocationHandler接口、要參與代理的目標(biāo)類必須實(shí)現(xiàn)對(duì)應(yīng)接口,比如上述的Student必須實(shí)現(xiàn)Person接口。

繼續(xù)以上述學(xué)生交班費(fèi)為例,更改為動(dòng)態(tài)代理模式:

JDK動(dòng)態(tài)代理中間類:該類需要實(shí)現(xiàn)InvocationHandler接口

// JDK動(dòng)態(tài)代理中間類
public class ProxyInvocationHandler implements InvocationHandler {
  // 被代理的對(duì)象
  private Object target;
  // ser方法注入?yún)?shù)
  public void setTarget(Object target) {this.target = target;}
  // 生成動(dòng)態(tài)代理類
  public Object getProxy(){
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
  }
  // 處理代理實(shí)例,并返回結(jié)果
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = method.invoke(target,args);
    return result;
  }
}

測(cè)試:

public static void main(String[] args) {
  // 獲取真實(shí)角色
  Student stu = new Student("張三三");
  // 動(dòng)態(tài)代理中間類對(duì)象
  InvocationHandlerProxyStudent proxyStudent = new InvocationHandlerProxyStudent();
  proxyStudent.setStu(stu);
  // 代理類實(shí)例
  Person proxy = (Person) proxyStudent.getProxy();
  // 代理類實(shí)例調(diào)用方法
  proxy.giveMoney();
}

上述程序,我們利用Proxy來生成代理類:

public Object getProxy(){
  return Proxy.newProxyInstance(this.getClass().getClassLoader(),
stu.getClass().getInterfaces(),this);
}

Proxy提供了靜態(tài)的獲取Proxy代理類的方法newProxyInstance,三個(gè)參數(shù)分別是1.類加載器 2.代理對(duì)象實(shí)現(xiàn)的接口 3. 調(diào)用處理程序(InvocationHandler)

在InvocationHandler官方文檔就已經(jīng)指出,每一個(gè)代理實(shí)例都關(guān)聯(lián)有一個(gè)InvocationHandler調(diào)用處理程序,所以這里填this即可

在使用代理類的時(shí)候首先我們創(chuàng)建需要被代理的真實(shí)對(duì)象和動(dòng)態(tài)代理中間類的對(duì)象,用set方法將真實(shí)對(duì)象交給中間類中的代理對(duì)象。在調(diào)用上述getProxy方法獲取代理類。動(dòng)態(tài)代理相對(duì)于靜態(tài)代理有些難以理解,這是因?yàn)殪o態(tài)代理的代理類可以在程序中顯式的被看到,而動(dòng)態(tài)代理中的代理類文件是緩存在Java虛擬機(jī),類名叫$Proxy0。

在虛擬機(jī)中生成的代理類中就會(huì)將我們所調(diào)用的方法內(nèi)置,我們?cè)趫?zhí)行proxy.giveMoney()的同時(shí),實(shí)際上是將giveMoney()方法作為參數(shù)傳進(jìn)invoke()的參數(shù)中去,而此時(shí)我們就可以將其他的操作交給invoke,由于所有代理對(duì)象在執(zhí)行時(shí)最終都會(huì)走invoke方法,所以也為我們的開發(fā)節(jié)省大量代碼

到此這篇關(guān)于Java代理模式與動(dòng)態(tài)代理之間的關(guān)系以及概念的文章就介紹到這了,更多相關(guān)Java代理模式與動(dòng)態(tài)代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java拆箱與裝箱實(shí)例詳解

    Java拆箱與裝箱實(shí)例詳解

    這篇文章主要介紹了Java拆箱與裝箱,結(jié)合實(shí)例形式詳細(xì)分析了Java拆箱與裝箱相關(guān)的數(shù)據(jù)類型轉(zhuǎn)換操作技巧,需要的朋友可以參考下
    2019-11-11
  • 基于java查找最長(zhǎng)字符串代碼實(shí)例

    基于java查找最長(zhǎng)字符串代碼實(shí)例

    這篇文章主要介紹了基于java查找最長(zhǎng)字符串代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Javadoc標(biāo)簽和Javadoc注釋規(guī)范說明

    Javadoc標(biāo)簽和Javadoc注釋規(guī)范說明

    這篇文章主要介紹了Javadoc標(biāo)簽和Javadoc注釋規(guī)范說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Action訪問Servlet的API的簡(jiǎn)單實(shí)例

    Action訪問Servlet的API的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄狝ction訪問Servlet的API的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • java?線程池如何執(zhí)行策略又拒絕哪些策略

    java?線程池如何執(zhí)行策略又拒絕哪些策略

    這篇文章主要介紹了java?線程池如何執(zhí)行策略又拒絕哪些策略,文章通過線程池的執(zhí)行方法?execute()?展開全篇內(nèi)容,需要的小伙伴可以參考一下
    2022-05-05
  • Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析

    Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析

    Spring的BeanFactoryPostProcessor是容器初始化的擴(kuò)展接口,允許在Bean實(shí)例化前修改或擴(kuò)展Bean的配置元數(shù)據(jù),本文給大家介紹Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析,感興趣的朋友一起看看吧
    2025-03-03
  • Spring中一個(gè)少見的引介增強(qiáng)IntroductionAdvisor

    Spring中一個(gè)少見的引介增強(qiáng)IntroductionAdvisor

    這篇文章主要為大家介紹了Spring中一個(gè)少見的引介增強(qiáng)IntroductionAdvisor實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • IntelliJ IDEA之高效代碼插件RainBow Brackets詳解

    IntelliJ IDEA之高效代碼插件RainBow Brackets詳解

    這篇文章主要介紹了IntelliJ IDEA之高效代碼插件RainBow Brackets詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • MyBatis insert語句返回主鍵和selectKey標(biāo)簽方式

    MyBatis insert語句返回主鍵和selectKey標(biāo)簽方式

    這篇文章主要介紹了MyBatis insert語句返回主鍵和selectKey標(biāo)簽方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java GUI界面初步入門示例【AWT包】

    java GUI界面初步入門示例【AWT包】

    這篇文章主要介紹了java GUI界面,結(jié)合簡(jiǎn)單實(shí)例形式分析了java使用AWT包進(jìn)行圖形界面操作相關(guān)使用技巧,需要的朋友可以參考下
    2020-01-01

最新評(píng)論

临城县| 东兴市| 改则县| 龙口市| 南宫市| 莱西市| 汽车| 平泉县| 云南省| 祁东县| 娄烦县| 临西县| 浑源县| 浦县| 涞源县| 肃南| 石狮市| 雅江县| 东乌| 九江县| 祁阳县| 博白县| 卓尼县| 鲁甸县| 措勤县| 吉安县| 鄂州市| 云梦县| 徐汇区| 车致| 贞丰县| 枣庄市| 恭城| 资兴市| 平遥县| 石林| 大方县| 汕头市| 轮台县| 乐陵市| 错那县|