摘要:總結動態代理的相關原理已經講解完畢,接下來讓我們回答以下幾個思考題。
【干貨點】 此處是【好好面試】系列文的第12篇文章。
文章目標主要是通過原理剖析的方式解答Aop動態代理的面試熱點問題,通過一步步提出問題和了解原理的方式,我們可以記得更深更牢,進而解決被面試官卡住喉嚨的情況。
問題如下
SpringBoot默認代理類型是什么
為什么不用靜態代理
JDK動態代理原理
CGLIB動態代理原理
JDK動態代理和CGLIB動態代理的區別
為什么CGLIB不能像JDK代理那樣,直接使用反射觸發目標函數
為什么CGLIB代理可以直接對類進行代理,而JDK代理卻一定要實現接口
大前提該文章是必須要懂的SpringAop系列的最后一篇文章,第一篇文章是你必須要懂的Spring-Aop之應用篇,第二篇文章是你必須要懂的Spring-Aop之源碼跟蹤分析Aop,最后一篇文章我們將會揭露Aop的原理,也就是動態代理。希望看完這最后一篇文章,大家對SpringAop都有一個全面的掌握,不管面試官如何問,都可以屌回去 ━━( ̄ー ̄*|||━━
溫馨提示:前面沒看的最好點擊瀏覽下?。?!說個坑爹的事
大家都知道,我有個習慣,在動手寫一篇文章之前會先將該文章相關的資料仔細琢磨一遍,然后再結合源碼再調試一遍,結果,說好的
看源碼也確實是
源碼確實有進行了是否是接口的判斷,但是問題來了,我調試的時候發現無論代理類是否有接口,最終都會被強制使用CGLIB代理,沒辦法,只能翻看SpringBoot的相關文檔,最終發現原來SpringBoot從2.0開始就默認使用Cglib代理了,好家伙,怪不得我調試半天找不到原因。
那么如何解決呢?肯定是通過配置啦,按照如下配置即可
在application.properties文件中配置 spring.aop.proxy-target-class=false
即可。
【劃重點】 曾經遇見過面試官問,SpringBoot默認代理類型是什么?看完該篇文章,我們就可以果斷的回答是Cglib代理了。通過調試代碼發現的規則,我想我這輩子都不會忘記這個默認規則。動態代理原理剖析 什么是代理
簡單來說,就是在運行的時候為目標類動態生成代理類,而在操作的時候都是操作代理類,代理模式有個顯而易見的好處,那便是可以在不改變對象方法的情況下對方法進行增強。試想下,我們在你必須要懂的Spring-Aop之應用篇有提到使用Aop來做權限認證,如果不用Aop,那么我們就必須要為所有需要權限認證的方法都加上權限認證代碼,聽起來就覺得蛋疼,你覺得對不對?
為什么不用靜態代理靜態代理類不是說不可以用,如果只有一個類需要被代理,那么自然可以用,如
這是在你必須要懂的Spring-Aop之應用篇使用的一個例子類,該類的作用只是打印出我要買東西。
代理類如下
可以看到這個BuyProxy代理類只是塞了一個IBuyServcie接口進行,而且自身也實現了接口IBuyService,而在buyItem方法被調用的時候會先做自己的操作,再調用塞進去的接口的buyItem方法。
測試類很簡單,如下
運行后很自然而然的打印出
靜態代理就是簡單,但是弊端也很明顯,如果有多個類都需要同樣的代理,都實現了同樣的接口,那么如果使用靜態代理的話,我們就要構造多個Proxy類,就會造成類爆炸。
而使用了Aop后,也就是動態代理后,便可以一次性解決該問題了,具體可以看你必須要懂的Spring-Aop之應用篇中的操作方法。
這里給出一個JDK動態代理的demo
首先給出一個簡單的業務類,Hello類和接口
真正實現了類的代理功能的其實就是這個實現了接口InvocationHandler的JdkProxy類
我們可以看到其中必須實現的方法是invoke,可以看到invoke方法的參數帶有Method對象,這個就是我們的目標Method,現在我們的目的就是要在這個Method在被調用前后實現我們的業務,可以看到在method.invoke反調前后實現了before和after業務。
這里再給出一個Main測試類,作用是取得Hello的代理類,然后調用其中的say方法。
運行結果如下
原理很簡單 在JdkProxyMain中hello調用say的時候,由于Hello已經被“代理”了,所以在調用say函數的時候其實是調用JdkProxy類中的invoke函數,而在invoke函數中先是實現了before函數才實現Object result = method.invoke(target, args),這一句其實是調用say函數,而后才實現after函數,于是這樣就可以不必在改動目標類的前提下實現代理了,并且不會像靜態代理那樣導致類爆炸。
CGLIB動態代理原理先給出一個Cglib動態代理的demo
【思考題一】為什么CGLIB代理可以直接對類進行代理,而JDK代理卻一定要實現接口呢?答案見問末?。。?/pre>核心類是實現了MethodInterceptor的CGlibProxy類
可以看到其中實現了方法intercept,先是在目標函數被調用前實現自己的業務,比如before()和after(),之后再通過 proxy.invokeSuper(obj, args) 觸發目標函數。
【思考題二】為什么這里不像JDK代理那樣,直接使用反射[method.invoke(target, args)]觸發目標函數?答案見問末?。。?/pre>最后給出入口類
最后給出運行類,運行類如下
可以看到運行結果
原理很簡單 在CglibProxyMain中hello調用say的時候,由于Hello已經被“代理”了,所以在調用say函數的時候其實是調用CGlibProxy類中的intercept函數。
總結動態代理的相關原理已經講解完畢,接下來讓我們回答以下幾個思考題。
「思考解惑一」為什么CGLIB代理可以直接對類進行代理,而JDK代理卻一定要實現接口呢?
可以從我們上面的例子看出,在JdkProxy類中取得代理類的方式是
(T)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this)
而在CGlibProxy類中取得代理類的方式是
(T) Enhancer.create(cls, this)
兩種取得代理類的方式不同,導致了一個需要實現接口,一個不需要。「思考解惑二」為什么這里不像JDK代理那樣,直接使用反射[method.invoke(target, args)]觸發目標函數?
首先要進行反射觸發函數,要取得對應的method,以及該method所屬對象,也就是target,再次是args方法參數,而我們看下調試界面可以從界面看到,目標對象obj并不是Hello對象,二是被CGLIB代理過的對象,因此無法像JDK代理那樣直接通過反射搞定。
最后的最后鑒于很多朋友都來找我聊《好好面試》相關的問題,本人也比較忙,無法一一應答,為此在此創建了一個微信群,有興趣的可以加入,只聊面試和技術相關。
如果過期了,可以在關注公眾號,在公眾號上喊我一聲,說要加群即可。
[好好面試] 系列文推薦:
你必須要懂的Spring-Aop之源碼跟蹤分析Aop
你必須要懂的Spring-Aop之應用篇
你所不知道的HelloWorld背后的原理
連引用都答不上,憑什么說你是Java服務端開發
你是否了解Spring中bean的生命周期呢?
開發必學,io&nio
你所不知道的HelloWorld背后的原理
如何基于spring動態注冊bean
拓展spring組件之自定義標簽
基于spring實現事件驅動
Java日常干貨
Java&Spring系列筆記[gomicro微服務] 系列文推薦:
go微服務系列之一
go微服務系列之二
go微服務系列之三
go微服務系列之四
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75802.html
摘要:用戶態不能干擾內核態所以指令就有兩種特權指令和非特權指令不同的狀態對應不同的指令。非特權指令所有程序均可直接使用。用戶態常態目態執行非特權指令。 這是我今年從三月份開始,主要的大廠面試經過,有些企業面試的還沒來得及整理,可能有些沒有帶答案就發出來了,還請各位先思考如果是你怎么回答面試官?這篇文章會持續更新,請各位持續關注,希望對你有所幫助! 面試清單 平安產險 飛豬 上汽大通 浩鯨科...
摘要:思考之所以會選擇為切入點,是因為通過命名可以看出這是用來構建代理強化對象的地方,并且由于是先將目標類加載到內存中,之后通過修改字節碼生成目標類的子類,因此我猜測強化是在目標類實例化后觸發的時候進行的。 【干貨點】 此處是【好好面試】系列文的第11篇文章??赐暝撈恼?,你就可以了解Spring中Aop的相關使用和原理,并且能夠輕松解答Aop相關的面試問題。更重要的是,很多人其實一看源碼就...
摘要:干貨點此處是好好面試系列文的第篇文章。而這也是出現的原因,沒錯,就是被設計出來彌補短板的。運行結果如下運行結果可想而知,的通過驗證,的失敗。 【干貨點】此處是【好好面試】系列文的第10篇文章??赐暝撈恼?,你就可以了解Spring中Aop的相關使用和原理,并且能夠輕松解答Aop相關的面試問題。 在實際研發中,Spring是我們經常會使用的框架,畢竟它們太火了,也因此Spring相關的知...
摘要:從使用到原理學習線程池關于線程池的使用,及原理分析分析角度新穎面向切面編程的基本用法基于注解的實現在軟件開發中,分散于應用中多出的功能被稱為橫切關注點如事務安全緩存等。 Java 程序媛手把手教你設計模式中的撩妹神技 -- 上篇 遇一人白首,擇一城終老,是多么美好的人生境界,她和他歷經風雨慢慢變老,回首走過的點點滴滴,依然清楚的記得當初愛情萌芽的模樣…… Java 進階面試問題列表 -...
閱讀 1990·2021-09-22 16:05
閱讀 9255·2021-09-22 15:03
閱讀 2880·2019-08-30 15:53
閱讀 1698·2019-08-29 11:15
閱讀 903·2019-08-26 13:52
閱讀 2348·2019-08-26 11:32
閱讀 1798·2019-08-26 10:38
閱讀 2562·2019-08-23 17:19