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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

为什么要用动态代理?静态代理与动态代理详解

發布時間:2025/1/21 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么要用动态代理?静态代理与动态代理详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

代理模式:

代理模式在Java中特別常見,如spring AOP功能就是用代理來實現的。代理模式作用是:在不修改被代理對象功能的基礎上,通過對代理類進行擴展,進行一些功能上的附加與增強。
一般使用代理模式我們需要先定義一個接口,靜態代理只是一種簡單的java代碼功能擴展。而動態代理利用了反射機制,使用更簡單,但背后邏輯…先說明一點,動態代理代理的是接口,而不是類Proxy類產生的代理對象是Proxy的一個實例,這個實例實現了我們定義的接口


靜態代理:

舉一個黃牛代理買票的例子:

public interface BuyTicket {//買票void buyTicket(); }

我自己買票,買不到

public class CommonPerson implements BuyTicket {@Overridepublic void buyTicket() {System.out.println("我自己在12306買不到票!");} }

我在智行火車票上加錢搶票,找黃牛代理

public class HuangNiu implements BuyTicket {//我買不到票,我需要被代理CommonPerson person = new CommonPerson();@Overridepublic void buyTicket() {person.buyTicket();System.out.println("我是黃牛,買票找我,出票成功!");}public static void main(String[] args) {HuangNiu huangNiu = new HuangNiu();huangNiu.buyTicket();} }

打印結果:

可以看出,我們自己買不到票,找黃牛代理,代理類可以幫助我們實現功能增強。


動態代理(jdk):

動態代理通過java反射機制,獲取某個被代理類的所有接口,并創建代理類。接口類和被代理類同上:

import Proxy.BuyTicket; import Proxy.CommonPerson;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;/*** Description:* Created by CWG on 2020/8/29 10:34*/ public class HuangNiu implements InvocationHandler {private CommonPerson person;public HuangNiu(CommonPerson person) {this.person = person;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object res = method.invoke(person, args);System.out.println("我是黃牛,買票找我,出票成功!");return res;}public static void main(String[] args) {//被代理類CommonPerson person = new CommonPerson();//代理類HuangNiu huangNiu = new HuangNiu(person);//生成代理對象:注意這里生成的代理對象只能是接口BuyTicket buyTicket = (BuyTicket) Proxy.newProxyInstance(CommonPerson.class.getClassLoader(),CommonPerson.class.getInterfaces(),huangNiu);//調用代理對象方法buyTicket.buyTicket();} }

打印結果:

可以發現功能與靜態代理一樣,不同的是靜態代理每次都要重寫接口中方法,而動態代理使我們免于去重寫接口中的方法,著重于去擴展相應的功能或是方法的增強,雖然在此示例中可能看不出,可能看上去比靜態代理更復雜,當我們在實際開發環境下,接口中方法很多的時候,就可以發現動態代理的便捷,會大大減少項目中的業務量。


動態代理解讀:

Proxy類

在上例main測試方法中,用到了Proxy.newProxyInstance()方法。動態代理涉及了一個非常重要的類Proxy。正是通過Proxy的靜態方法newProxyInstance才會動態創建代理

public static Object newProxyInstance(ClassLoader var0, Class<?>[] var1, InvocationHandler var2) throws IllegalArgumentException
  • ClassLoader var0:對應參數 CommonPerson.class.getClassLoader()即被代理類的類加載器
  • Class<?>[] var1:對應參數 CommonPerson.class.getInterfaces()即獲取被代理類實現的所有接口
  • InvocationHandler var2:對應參數 代理類huangNiu, 為一個InvocationHandler實現對象

InvocationHandler接口

public interface InvocationHandler {Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }

代理類需要實現InvocationHandler 接口,invoke()雖然沒有被顯式調用,但該方法也一定被執行了,對應的三個參數分別傳入的是:代理類的實例,method是調用的方法,即需要執行的方法;args是方法的參數;

就本人目前水平,想看懂動態代理背后如何實現有點吃力,以后看懂再接著寫吧,現在也只是知道動態代理是干嘛用的,如果有興趣繼續探究可以參考下面的參考文章3。

參考文章:
1、jdk動態代理與cglib動態代理實現原理
2、為什么要使用java動態代理
3、JDK的動態代理原理

總結

以上是生活随笔為你收集整理的为什么要用动态代理?静态代理与动态代理详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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