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