Skip to content

值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎

機場接送

Menu
  • 首頁
  • 裝潢設計
  • 旅遊天地
  • 環保清潔
Menu

Java動態代理與靜態代理以及它能為我們做什麼_網頁設計公司

Posted on 2021-06-292021-06-29 by admin

※南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

  相信我們在網上和平時學習和工作中或多或少都接觸過Java的代理模式,經常聽到什麼靜態代理、動態代理的一些名詞。但我們是否真的很清楚這些呢?至少我在面試時,發現很多人並不很清楚。

  首先代理比較好理解,就是幫一個人,或者一類人做一些事情。遷移到面向對象的程序設計中,代理就是幫一個類去做一些事情,而這個代理的工具我們就稱為代理類。

  通過代理的方式去做事有什麼好處呢?這就好比工廠和分銷商做的事情一樣,工廠可以直賣一些自己的產品,分銷商同樣也可以賣工廠生產的產品,那麼為什麼還有分銷商的存在呢?因為分銷商可以提供一些額外的服務,或者在銷售的過程中能夠完成一些其他的事情,比如組合銷售、根據本地情況做活動等,而這些可能是工廠不想關心或者也管不過來的。這樣的功能和角色承包給代理商就會使得分工比較明晰,並且又能夠提供一些額外或者定製的服務。

 

靜態代理

  Java中的代理方式可以分為靜態代理和動態代理。靜態代理的含義是代理類/對象在我們關心的程序運行前就已經確定或存在。靜態代理比較好理解,我們在日常工作中也是經常用到,比如一個已經存在的接口,我們不期望去更改它,但是現在要在原邏輯上新加一些邏輯或功能,比如原接口方法調用完成后發送一個消息之類的。於是我們可以創建一個類,同樣實現原接口,並且把之前存在的接口當做成員變量注入進來,調用其中的方法,並添加我們需要的功能。

  靜態代理的類圖如下所示,需要被代理的實現類和代理類都實現了抽象接口AbstractInterface,而InterfaceProxy和InterfaceImpl間是聚合關係。

  

 

 

 

   來看一段示例代碼,ProductAuditCallbackService 是我們已有的一個接口,出於某些原因,這個接口不能繼續對外使用,我們需要定義一個新的接口並且名稱還要一樣(主要是方便客戶理解和對應原接口),但是我們需要添加一點“新邏輯”。因此我們可以同樣實現 ProductAuditCallbackService,ProductAuditCallbackServiceProxy 就是我們的代理類,之後外部調用就可以實例化我們的代理類,調用同名方法就好了。

 

 1 public class ProductAuditCallbackServiceProxy implements ProductAuditCallbackService {
 2 
 3     @Resource
 4     private ProductAuditCallbackService productAuditCallbackService;
 5 
 6     @Override
 7     public Result<Void> auditProduct(ProductAuditRequest request, String auditStatus) {
 8         if (auditStatus == "DELETED") {
 9             return new Result<>();
10         }
11         return productAuditCallbackService.auditProduct(request, auditStatus);
12     }
13 
14 
15 ...
16 }

 

 

 

 

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

動態代理

  動態代理的作用和靜態代理一樣,主要的區別就在於需要在運行時生成代理類。在使用動態代理時,我們還需要定義一個在代理類和委託類之間的中介類,並且中介類需要實現 java.lang.reflect.InvocationHandler 接口。

 1 package java.lang.reflect;
 2 
 3 /**
 4  * {@code InvocationHandler} is the interface implemented by
 5  * the <i>invocation handler</i> of a proxy instance.
 6  *
 7  * <p>Each proxy instance has an associated invocation handler.
 8  * When a method is invoked on a proxy instance, the method
 9  * invocation is encoded and dispatched to the {@code invoke}
10  * method of its invocation handler.
11  *
12  * @author      Peter Jones
13  * @see         Proxy
14  * @since       1.3
15  */
16 public interface InvocationHandler {
17 
18     public Object invoke(Object proxy, Method method, Object[] args)
19         throws Throwable;
20 }

  

  動態代理在框架類的代碼中用到的頻率並不低,而且能夠使我們的代碼看起來更高級一些,所以何樂而不為呢? 讓我們來看一些實際的例子。

  MethodInvocationHandler是一个中介類,實現了InvocationHandler接口,MethodMonitor 這個類的功能就是要統計我們的委託類的對象business中的方法被調用的次數和耗時,由於其主要功能不是我們關注的主要內容,所以忽略其實現。

 1 public class MethodInvocationHandler implements InvocationHandler {
 2 
 3     //被代理對象
 4     private Object business;
 5 
 6     private final MethodMonitor methodMonitor;
 7 
 8     public MethodInvocationHandler(MethodMonitor methodMonitor) {
 9         this.methodMonitor = methodMonitor;
10     }
11 
12     /**
13      * 代理方法
14      */
15     @Override
16     public Object invoke(Object proxy, Method method, Object[] args)
17             throws Throwable {
18 
19         long startTime = System.currentTimeMillis();
20 
21         Object result = method.invoke(this.business, args);
22 
23         //方法調用統計
24         this.methodMonitor.methodCount(this.business.getClass().getSimpleName() + POINT + method.getName(), startTime);
25         return result;
26     }
27 
28 }

  其餘示例代碼及外部調用示例如下,我們的Business類裏面擁有三個方法。MethodSampleClient 則是一個封裝起來的客戶端。我們不想讓外部客戶端感知我們的實現以及和Business的關係,於是我們在MethodSampleClient中定義了一個成員變量proxy,當外部需要Business提供的一些功能時,我們通過proxy為其提供。Proxy.newProxyInstance() 則是我們實例化一個代理類的方式,喲,這還是個工廠模式,可以閱讀一些這個方法的說明,需要傳入的三個參數依次是:需要被代理的類的ClassLoader,被代理類需要被代理的接口的集合,中介處理類的實例。

  這裏Business我寫的是一個確定的類,其實真正在實際開發工作中,我們往往定義的抽象的接口或抽象類,知道運行時才會確定到底是哪個實現類的實例,這樣可能更容易理解一些:運行時確定委託類的實現類,運行時生成代理類,並調用對應的委託類的方法。

 

 1 public class Business {
 2 
 3     public void createJob() {
 4         System.out.println("test createJob");
 5     }
 6 
 7 
 8     public void processJob() {
 9         System.out.println("test processJob");
10     }
11 
12     public void closeJob() {
13         System.out.println("test closeJob");
14     }
15 
16 }
17 
18 
19 
20 public class MethodSampleClient {
21 
22     private Business business;
23 
24     @Getter
25     private Object proxy;
26 
27     private InvocationHandler invocationHandler;
28 
29 
30     public void init() {
31         this.business = new Business();
32         this.invocationHandler = new MethodInvocationHandler(new MethodMonitor());
33         this.proxy = bind(this.business, invocationHandler);
34     }
35 
36     /**
37      * 綁定對象, 直接初始化並返回代理類供客戶端使用
38      */
39     public Object bind(Object business, InvocationHandler invocationHandler) {
40         return Proxy.newProxyInstance(
41                 //被代理類的ClassLoader
42                 business.getClass().getClassLoader(),
43                 //要被代理的接口,本方法返回對象會自動聲稱實現了這些接口
44                 business.getClass().getInterfaces(),
45                 //代理處理器對象
46                 invocationHandler);
47     }
48     
49 }    
50 
51 
52 /**
53 *  A simple client test class
54 */
55 public class Test {
56 
57     public void main(String[] args) {
58         MethodSampleClient methodSampleClient = new MethodSampleClient();
59         methodSampleClient.init();
60 
61         methodSampleClient.getProxy().createJob();
62         methodSampleClient.getProxy().processJob();
63         methodSampleClient.getProxy().closeJob();
64     }
65 
66 }

   

  為了說清楚這個過程,竟然還真的寫了不少代碼,看起來比較繁瑣。總結一下,動態代理無非按照下面的步驟來編寫代碼:

  • 首先明確需要被代理的委託類。
  • 實現 InvocationHandler 接口,定義一个中介類。
  • 用 Proxy.newProxyInstance() 實例化代理類,並在客戶端代碼中直接使用。

  好了,大概差不多了,最重要的是能夠在實際工作中有意識地去使用並體會其作用 —— 軟件開發是經驗驅動不是知識驅動。

 

 

 

 

  

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

好站推薦

  • 健康醫療 減重知識專區
  • 婚紗世界 婚紗攝影寫真網
  • 成人話題 未滿18請勿進入
  • 流行時尚 時下流行愛美情報
  • 理財資訊 當舖借貸信用卡各式理財方法
  • 生活情報 各行各業情報資訊
  • 科技資訊 工業電子3C產品
  • 網路資訊 新奇趣味爆笑內容
  • 美食分享 全台各式名產 伴手禮
  • 裝潢設計 買屋賣屋裝修一羅框
  • 視覺設計 T恤、團體服、制服、polo衫

近期文章

  • 美擬降大陸鋼品關稅 中鋼回應了
  • 搶標地上權展店 業者複製「全聯模式」
  • 擁雙利多 巧新營運吃補丸
  • 亞德客、氣立 全年營收拚攻頂
  • 交屋入帳衝刺 營建F4業績看旺

標籤

USB CONNECTOR  到府月嫂 南投搬家公司費用 古典家具推薦 台中室內設計 台中搬家 台中搬家公司 台中電動車 台北網頁設計 台東伴手禮 台東名產 地板施工 大圖輸出 如何寫文案 婚禮錄影 宜蘭民宿 家具工廠推薦 家具訂製工廠推薦 家具訂製推薦 實木地板 床墊 復刻家具推薦 新竹婚宴會館 木地板 木質地板 柚木地板 桃園機場接送 桃園自助婚紗 沙發修理 沙發換皮 海島型木地板 潭子電動車 牛軋糖 租車 網站設計 網頁設計 網頁設計公司 貨運 超耐磨木地板 銷售文案 隱形鐵窗 電動車 馬賽克拼貼 馬賽克磁磚 馬賽克磚

彙整

  • 2022 年 5 月
  • 2022 年 4 月
  • 2022 年 3 月
  • 2022 年 2 月
  • 2022 年 1 月
  • 2021 年 12 月
  • 2021 年 11 月
  • 2021 年 10 月
  • 2021 年 9 月
  • 2021 年 8 月
  • 2021 年 7 月
  • 2021 年 6 月
  • 2021 年 5 月
  • 2021 年 4 月
  • 2021 年 3 月
  • 2021 年 2 月
  • 2021 年 1 月
  • 2020 年 12 月
  • 2020 年 11 月
  • 2020 年 10 月
  • 2020 年 9 月
  • 2020 年 8 月
  • 2020 年 7 月
  • 2020 年 6 月
  • 2020 年 5 月
  • 2020 年 4 月
  • 2020 年 3 月
  • 2020 年 2 月
  • 2020 年 1 月
  • 2019 年 12 月
  • 2019 年 11 月
  • 2019 年 10 月
  • 2019 年 9 月
  • 2019 年 8 月
  • 2019 年 7 月
  • 2019 年 6 月
  • 2019 年 5 月
  • 2019 年 4 月
  • 2019 年 3 月
  • 2019 年 2 月
  • 2019 年 1 月
  • 2018 年 12 月
©2022 值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎ | Built using WordPress and Responsive Blogily theme by Superb