摘要:緊接著上節,為了解決靜態代理的問題,出現了動態代理,假設動態代理是一個代購公司,私有變量為動態生成的具體的真實對象,可代購對應的產品。這個注釋是說提供個一個靜態方法來創建代理類和代理實例,它也是所有由此方法創建的代理類的父類。
緊接著上節,為了解決靜態代理的問題,出現了動態代理, 假設動態代理是一個代購公司,私有變量Object factory為動態生成的具體的真實對象,可代購對應的產品 。代碼:
/** * 動態代理 */ public class DynamicProxyCompanyC implements InvocationHandler { // 被代理的對象,即真實對象 private Object factory; public Object getFactory() { return factory; } public void setFactory(Object factory) { this.factory = factory; } // 通過proxy獲取動態代理的對象 public Object getProxyInstance() { //第三個參數是InvocationHandler,傳入自身說明此proxy對象是和自身的invoke方法合作的,代理對象方法調用會經過下面invoke的增強 return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this); } @Override /**通過動態代理對象對方法進行增強 * @param proxy 代理對象 * @param method 要增強的方法(攔截的方法) * @param args 方法參數 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { dosomeThingBefore(); Object ret = method.invoke(factory, args);// 通過反射機制調用方法 dosomeThingAfter(); return ret; } public void dosomeThingBefore() { System.out.println("售前服務,負責產品調研,興趣愛好"); } public void dosomeThingAfter() { System.out.println("售后服務,包裝丶送貨上門一條龍服務"); } }
測試類:
public class Proxytest { public static void main(String[] args) { // 代購公司C,負責代購所有產品 DynamicProxyCompanyC proxy = new DynamicProxyCompanyC(); // 日本有家A公司生產男性用品 ManToolFactory dogToolFactory = new AManFactory(); // 代購A公司的產品 proxy.setFactory(dogToolFactory); // 創建A公司的代理對象 ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance(); // 代理對象完成代購男性用品 proxyObject.saleManTool("D"); System.out.println("--------------"); // 日本有家B公司生產女性用品 WomanToolFactory womanToolFactory = new BWomanFactory(); // 代購B公司的產品 proxy.setFactory(womanToolFactory); // 創建B公司的代理對象 WomanToolFactory proxyObject1 = (WomanToolFactory) proxy.getProxyInstance(); // 代理對象完成代購女性用品 proxyObject1.saleWomanTool(1.8); } } // 售前服務,負責產品調研,興趣愛好 // A工廠出售男性用品,D罩杯 // 售后服務,包裝丶送貨上門一條龍服務 // -------------- // 售前服務,負責產品調研,興趣愛好 // B工廠生產女性用品,長度1.8米 // 售后服務,包裝丶送貨上門一條龍服務
動態代理解決了上節說的開閉原則,那么接下來我們要解密動態代理的原理,重點類DynamicProxyCompanyC
1.實現了InvocationHandler接口;
2.通過proxy獲取動態代理的對象。
根據我們此例子里面來說,動態代理就類似一個代購公司,可代購所有產品,需要購買哪個產品的時候就實例化一個真實對象(如測試類需要男性用品則將接口引用指向真實對象AManFactory),根據真實對象創建代理對象來執行具體的方法,圖解如下:
Proxy:接下來我們先初步看一下JDK里面的Proxy這個源碼。
這個注釋是說Proxy提供個一個靜態方法來創建代理類和代理實例,它也是所有由此方法創建的代理類的父類。
靜態方法創建代理實例即方法newProxyInstance(ClassLoader loader,Class>[]interfaces,InvocationHandler h);
InvocationHandler 是一個接口,定義了invoke(Object proxy, Method method, Object[] args)方法
總的來說Proxy專門負責new一個實例(真實對象),而具體方法做什么,業務怎樣增強就由InvocationHandler(抽象對象)的invoke方法(抽象對象即接口定義的方法)來決定。
接下來我們要搞清楚動態代理的底層原理,首先我們調試一下test類,會發現 ManToolFactory proxyObject = (ManToolFactory) proxy.getProxyInstance()中創建的proxyObject 對象類名是$Proxy0,是ManToolFactory接口的實現類。但是我們項目工程里面卻沒有$Proxy0這個類,那它究竟是怎么出現的,下節講解。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73671.html
摘要:值得一提的是由于采用動態創建子類的方式生成代理對象,所以不能對目標類中的方法進行代理。動態代理中生成的代理類是子類,調試的時候可以看到,打開源碼可看到實現了和也就實現方法。 前面講到了動態代理的底層原理,接下來我們來看一下aop的動態代理.Spring AOP使用了兩種代理機制:一種是基于JDK的動態代理,一種是基于CGLib的動態代理. ①JDK動態代理:使用JDK創建代理有一個限制...
摘要:對象什么時候被回收答可達性分析,當發現某個類不被引用,類會被回收類的生命周期與動態代理關系動態代理是沒有源文件,直接生成字節碼的,加載到上面的。 上節講到動態代理生成的類為$Proxy0,但是在我們項目里面卻不存在,實際我們是用了這個實現類調用了方法,想要知道這個問題,首先要理解類的完整生命周期. 類的完整生命周期 showImg(https://segmentfault.com/im...
摘要:總結動態代理的相關原理已經講解完畢,接下來讓我們回答以下幾個思考題。 【干貨點】 此處是【好好面試】系列文的第12篇文章。文章目標主要是通過原理剖析的方式解答Aop動態代理的面試熱點問題,通過一步步提出問題和了解原理的方式,我們可以記得更深更牢,進而解決被面試官卡住喉嚨的情況。問題如下 SpringBoot默認代理類型是什么 為什么不用靜態代理 JDK動態代理原理 CGLIB動態代理...
摘要:修飾者模式設計模式中的修飾者模式能動態地給目標對象增加額外的職責。修飾者模式調用的時序圖如下圖所示。的實現原理和修飾者模式類似。 ?在上邊一篇文章中我們介紹了Spring AOP的基本概念,今天我們就來學習一下與AOP實現相關的修飾者模式和Java Proxy相關的原理,為之后源碼分析打下基礎。 修飾者模式 ?Java設計模式中的修飾者模式能動態地給目標對象增加額外的職責(Respon...
閱讀 1209·2021-11-17 09:33
閱讀 3617·2021-09-28 09:42
閱讀 3345·2021-09-13 10:35
閱讀 2504·2021-09-06 15:00
閱讀 2450·2021-08-27 13:12
閱讀 3617·2021-07-26 23:38
閱讀 1856·2019-08-30 15:55
閱讀 546·2019-08-30 15:53