Spring AOP實現(xiàn)原理分析

Spring的核心是IOC與AOP逾雄,IOC主要是依賴關系的管理阀溶,依賴查詢腻脏,依賴注入,在之前bean的生命周期文章中已經(jīng)對bean的生命周期做了相對多的分析银锻,這里以前探討下AOP的實現(xiàn)原理永品。

關鍵類

  • AspectJAwareAdvisorAutoProxyCreator Spring啟動時的beanPostProcessor,bean生命周期中經(jīng)郴魑常可以看到beanPostProcessor在起作用鼎姐,AOP也是基于IOC來實現(xiàn)的。
  • DefaultAopProxyFactory.createAopProxy(AdvisedSupport config) 創(chuàng)建AOP代理類更振,這樣才可以實現(xiàn)AOP
  • AopNamespaceHandler aop標簽解析的handler
  • ConfigBeanDefinitionParser ,aop config標簽的解析類炕桨。

分析

  1. 首先搭建一個能運行 Spring AOP的demo,參考早期的一篇文章Spring AOP入門

預覽一下配置文件


image.png
  1. 運行方式不變肯腕,在Bean生命周期-實例化ApplicationContext中的運行方式谋作。
// Spring加載配置文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
  1. spring在啟動的時候加載配置文件的方式不變,變化的只是其解析配置文件的方式乎芳,而實例化ApplicationContext中加載配置文件過程

refresh
-> obtainFreshBeanFactory
-> refreshBeanFactory
-> AbstractRefreshableApplicationContext.loadBeanDefinitions(beanFactory)
-> ...
-> XmlBeanDefinitionReader.loadBeanDefinitions(Resource resource)
-> DefaultBeanDefinitionDocumentReader.parseBeanDefinitions

以上過程在bean生命周期中都有提到過遵蚜,以上沒有變化。

區(qū)別在于<aop:config>是自定義的標簽奈惑,這次走的是parseCustomElement方法

image.png

  1. 找到自定義元素的NamespaceHandler吭净,NamespaceHandler的映射關系定義在 META/spring.handlers文件中铐尚。Spring各個jar包中的spring.handlers都會生效蟆肆。

NameSpaceHandler的映射關系存儲在DefaultNamespaceHandlerResolver中今穿,自定義的aop:config標簽找到的Handler是AopNamespaceHandler

image.png
  1. AopNamespaceHandler是在namespaceHandlerResolver進行resolve的時候蒋川,實例化并且調(diào)用init方法的擎勘,然后AopNamespaceHandler進行parse硝全。
image.png

AopNamespaceHandler在parse的時候批糟,找到標簽對應的Parser再進行parse赚爵,因此[aop:config]標簽又交給了ConfigBeanDefinitionParser來解析庶柿。

  // AopNamespaceHandler調(diào)用的parse方法
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        return findParserForElement(element, parserContext).parse(element, parserContext);
    }
  1. ConfigBeanDefinitionParser的解析過程村怪,其剛開始配置configureAutoProxyCreator,會配置AspectJAwareAdvisorAutoProxyCreator這個類做為spring的bean浮庐。

ConfigBeanDefinitionParser.parse
-> configureAutoProxyCreator
-> AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element)
-> ...

image.png
  1. 在解析其它標簽的時候甚负,大致都是注冊一個bean,pointcut,advisor审残,aspect內(nèi)部解析就不相信說明了梭域,這次我們只是概覽。
image.png
  1. 解析完aop的元素之后搅轿,其它的過程仍然和bean生命周期相同病涨,不同之處則在于如果配置了AOP相關標簽,在處理bean的時候璧坟,beanPostProcessor在bean生命周期內(nèi)多處有影響既穆,足以改變bean的結(jié)構(gòu)赎懦。

AOP的實現(xiàn)方式基于IOC,通過beanPostProcessor來自定義bean的結(jié)構(gòu)

image.png
  1. 在bean實例化完成之后循衰,會調(diào)用beanPostProcessor的postProcessAfterInitialization方法铲敛,這個生命階段,我們在Bean生命周期匯總這篇文章里也提到過会钝。

AspectJAwareAdvisorAutoProxyCreator的postProcessAfterInitialization方法再其父類AbstractAutoProxyCreator中實現(xiàn)伐蒋,其會對已經(jīng)實例化的bean進行wrap。

而對bean進行wrap的時候迁酸,就是使用ProxyFactory createAopProxy先鱼,最終會走到DefaultAopProxyFactory的createAopProxy方法。

可以看到:

  • 如果bean的類是接口或者類是JDK內(nèi)部的代理類奸鬓,其使用 JDK的動態(tài)代理類
  • 其它情況是CGLIB來實現(xiàn)
image.png
  1. 最后生成的HelloWorld長這個樣子焙畔。其已經(jīng)是生成的代理類了,AOP功能已經(jīng)生效串远。
image.png
  1. 創(chuàng)建代理類之后宏多,其余的過程與bean的生命周期基本一致

總結(jié)

aop的功能也是借助spring對bean的管理來實現(xiàn)的,弄明白了bean的整個過程澡罚,spring的其它模塊理解起來都會很輕松伸但。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市留搔,隨后出現(xiàn)的幾起案子更胖,更是在濱河造成了極大的恐慌,老刑警劉巖隔显,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件却妨,死亡現(xiàn)場離奇詭異,居然都是意外死亡括眠,警方通過查閱死者的電腦和手機彪标,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哺窄,“玉大人捐下,你說我怎么就攤上這事∶纫担” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵奸柬,是天一觀的道長生年。 經(jīng)常有香客問我,道長廓奕,這世上最難降的妖魔是什么抱婉? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任档叔,我火速辦了婚禮,結(jié)果婚禮上蒸绩,老公的妹妹穿的比我還像新娘衙四。我一直安慰自己,他們只是感情好患亿,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布传蹈。 她就那樣靜靜地躺著,像睡著了一般步藕。 火紅的嫁衣襯著肌膚如雪惦界。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天咙冗,我揣著相機與錄音沾歪,去河邊找鬼。 笑死雾消,一個胖子當著我的面吹牛灾搏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播立润,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼狂窑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了范删?” 一聲冷哼從身側(cè)響起蕾域,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎到旦,沒想到半個月后旨巷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡添忘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年采呐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搁骑。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡斧吐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仲器,到底是詐尸還是另有隱情煤率,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布乏冀,位于F島的核電站蝶糯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏辆沦。R本人自食惡果不足惜昼捍,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一识虚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妒茬,春花似錦担锤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至团赁,卻和暖如春育拨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欢摄。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工熬丧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怀挠。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓析蝴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绿淋。 傳聞我的和親對象是個殘疾皇子闷畸,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本文是我自己在秋招復習時的讀書筆記,整理的知識點吞滞,也是為了防止忘記佑菩,尊重勞動成果,轉(zhuǎn)載注明出處哦裁赠!如果你也喜歡殿漠,那...
    波波波先森閱讀 12,284評論 6 86
  • 1.1 Spring IoC容器和bean簡介 本章介紹了Spring Framework實現(xiàn)的控制反轉(zhuǎn)(IoC)...
    起名真是難閱讀 2,577評論 0 8
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)佩捞,斷路器绞幌,智...
    卡卡羅2017閱讀 134,628評論 18 139
  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,702評論 2 22
  • 本來是準備看一看Spring源碼的一忱。然后在知乎上看到來一個帖子莲蜘,說有一群**自己連Spring官方文檔都沒有完全讀...
    此魚不得水閱讀 6,926評論 4 21