????記錄面試中問到的spring ioc 和 aop的概念和原理。
????Spring 底層 IoC 容器的設(shè)計實現(xiàn)也是非常完美的溉知,在整個 Spring 應(yīng)用上下文的生命周期和 Spring Bean 的生命周期的許多階段提供了相應(yīng)的擴展點陨瘩,供開發(fā)者自行擴展,使得框架非常的靈活级乍。
Spring擁有兩大特性:IoC和AOP舌劳。IoC,英文全稱Inversion of Control玫荣,意為控制反轉(zhuǎn)甚淡。AOP,英文全稱Aspect-Oriented Programming捅厂,意為面向切面編程贯卦。
Spring核心容器的主要組件是Bean工廠(BeanFactory)资柔,Bean工廠使用控制反轉(zhuǎn)(IoC)模式來降低程序代碼之間的耦合度,并提供了面向切面編程(AOP)的實現(xiàn)撵割。
簡單來說贿堰,Spring是一個輕量級的控制反轉(zhuǎn)(IoC)和面向切面編程(AOP)的容器框架。
?控制反轉(zhuǎn)(IoC)
控制反轉(zhuǎn)睁枕,簡單點說官边,就是創(chuàng)建對象的控制權(quán),被反轉(zhuǎn)到了Spring框架上外遇。
通常,我們實例化一個對象時契吉,都是使用類的構(gòu)造方法來new一個對象跳仿,這個過程是由我們自己來控制的,而控制反轉(zhuǎn)就把new對象的工交給了Spring容器捐晶。
IoC的主要實現(xiàn)方式有兩種:依賴查找菲语、依賴注入。
依賴注入是一種更可取的方式惑灵。
先來說說傳統(tǒng)使用java實例的不足山上,一般有兩種方式:
通過new關(guān)鍵字實例化一個對象;
通過工廠模式生產(chǎn)一個實例對象英支;
第一種方式必然導(dǎo)致調(diào)用者和被依賴對象存在硬編碼耦合佩憾,非常不利于項目升級的維護;第二種比第一種好很多干花,但是調(diào)用組件需要主動通過工廠去獲取被依賴的對象妄帘,這就會帶來調(diào)用組件與被依賴工廠的耦合。
那么IOC有什么好處呢?
調(diào)用者無需主動獲取被依賴的對象池凄,只要被動接受Spring容器為調(diào)用者的成員變量即可抡驼。總體來說就是主動變?yōu)楸粍又茁兀员环Q為控制反轉(zhuǎn)致盟。
場景
依賴注入一般有以下兩種:
設(shè)值注入:IoC容器使用成員變量的setter方法來注入被依賴對象;
構(gòu)造注入:IoC容器通過構(gòu)造器來注入被依賴對象尤慰;
建議采用設(shè)值注入為主馏锡,構(gòu)造注入為輔的注入策略。對于依賴關(guān)系無需變化的注入割择,盡量采用構(gòu)造注入眷篇;而其他依賴關(guān)系的注入,則考慮采用設(shè)值注入荔泳。
使用IoC容器的三個基本要點:
應(yīng)用程序的各組件面向接口編程蕉饼,這樣就可以將組件之間的耦合關(guān)系提升到接口層次虐杯,從而有有利于項目后期的發(fā)展;
應(yīng)用程序的各組件不再由程序主動創(chuàng)建昧港,而是由Spring容器來負(fù)責(zé)產(chǎn)生并初始化擎椰;
Spring采用配置文件或注解來管理Bean的實現(xiàn)類、依賴關(guān)系创肥,Spring容器則根據(jù)配置文件或注解达舒,利用反射來創(chuàng)建實例,并為之注入依賴關(guān)系叹侄。
?面向切面編程(AOP)
面向切面編程(AOP)就是縱向的編程巩搏。比如業(yè)務(wù)A和業(yè)務(wù)B現(xiàn)在需要一個相同的操作,傳統(tǒng)方法我們可能需要在A趾代、B中都加入相關(guān)操作代碼贯底,而應(yīng)用AOP就可以只寫一遍代碼,A撒强、B共用這段代碼禽捆。并且,當(dāng)A飘哨、B需要增加新的操作時胚想,可以在不改動原代碼的情況下,靈活添加新的業(yè)務(wù)邏輯實現(xiàn)芽隆。
在實際開發(fā)中浊服,比如商品查詢、促銷查詢等業(yè)務(wù)摆马,都需要記錄日志臼闻、異常處理等操作,AOP把所有共用代碼都剝離出來囤采,單獨放置到某個類中進行集中管理述呐,在具體運行時,由容器進行動態(tài)織入這些公共代碼蕉毯。
AOP主要一般應(yīng)用于簽名驗簽乓搬、參數(shù)校驗、日志記錄代虾、事務(wù)控制进肯、權(quán)限控制、性能統(tǒng)計棉磨、異常處理等江掩。
AOP涉及名詞
切面(Aspect):共有功能的實現(xiàn)。如日志切面、權(quán)限切面环形、驗簽切面等策泣。在實際開發(fā)中通常是一個存放共有功能實現(xiàn)的標(biāo)準(zhǔn)Java類。當(dāng)Java類使用了@Aspect注解修飾時抬吟,就能被AOP容器識別為切面萨咕。
通知(Advice):切面的具體實現(xiàn)。就是要給目標(biāo)對象織入的事情火本。以目標(biāo)方法為參照點危队,根據(jù)放置的地方不同,可分為前置通知(Before)钙畔、后置通知(AfterReturning)茫陆、異常通知(AfterThrowing)、最終通知(After)與環(huán)繞通知(Around)5種刃鳄。在實際開發(fā)中通常是切面類中的一個方法盅弛,具體屬于哪類通知,通過方法上的注解區(qū)分叔锐。
連接點(JoinPoint):程序在運行過程中能夠插入切面的地點。例如见秽,方法調(diào)用愉烙、異常拋出等。Spring只支持方法級的連接點解取。一個類的所有方法前步责、后、拋出異常時等都是連接點禀苦。
切入點(Pointcut):用于定義通知應(yīng)該切入到哪些連接點上蔓肯。不同的通知通常需要切入到不同的連接點上,這種精準(zhǔn)的匹配是由切入點的正則表達(dá)式來定義的振乏。
比如蔗包,在上面所說的連接點的基礎(chǔ)上,來定義切入點慧邮。我們有一個類调限,類里有10個方法,那就產(chǎn)生了幾十個連接點误澳。但是我們并不想在所有方法上都織入通知耻矮,我們只想讓其中的幾個方法,在調(diào)用之前檢驗下入?yún)⑹欠窈戏ㄒ湮剑敲淳陀们悬c來定義這幾個方法裆装,讓切點來篩選連接點,選中我們想要的方法。切入點就是來定義哪些類里面的哪些方法會得到通知哨免。
目標(biāo)對象(Target):那些即將切入切面的對象茎活,也就是那些被通知的對象。這些對象專注業(yè)務(wù)本身的邏輯铁瞒,所有的共有功能等待AOP容器的切入妙色。
代理對象(Proxy):將通知應(yīng)用到目標(biāo)對象之后被動態(tài)創(chuàng)建的對象』鬯#可以簡單地理解為身辨,代理對象的功能等于目標(biāo)對象本身業(yè)務(wù)邏輯加上共有功能。代理對象對于使用者而言是透明的芍碧,是程序運行過程中的產(chǎn)物煌珊。目標(biāo)對象被織入共有功能后產(chǎn)生的對象。
織入(Weaving):將切面應(yīng)用到目標(biāo)對象從而創(chuàng)建一個新的代理對象的過程泌豆。這個過程可以發(fā)生在編譯時定庵、類加載時、運行時踪危。Spring是在運行時完成織入蔬浙,運行時織入通過Java語言的反射機制與動態(tài)代理機制來動態(tài)實現(xiàn)。
Aspect Oriented Programming贞远,面向切面編程畴博,用于在模塊化方面的橫切關(guān)注點。AOP和OOP(Object Oriented Programming)互為補充蓝仲,可以這么理解:面向?qū)ο缶幊淌菑撵o態(tài)角度縱向考慮程序結(jié)構(gòu)俱病,面向切面編程則是從動態(tài)角度橫向考慮運行過程。比如一個日記記錄的功能袱结,代碼往往水平的散落在所有對象中亮隙,與被散布的對象的核心功能沒什么關(guān)系,這種散布在各個對象中的無關(guān)代碼被稱為“橫切代碼”垢夹,在OOP的設(shè)計中溢吻,它導(dǎo)致了大量代碼的重復(fù),從而不利于各個模塊的復(fù)用棚饵。
簡單的說煤裙,它是一個攔截器可以攔截一些過程,當(dāng)一個方法執(zhí)行噪漾,Spring AOP可以攔截一個方法的執(zhí)行硼砰,在這個方法執(zhí)行的前后添加一些功能。是一個典型代理模式的應(yīng)用欣硼。
使用場景
日志記錄题翰、審計、聲明式事務(wù)、安全性和緩存等豹障。
總結(jié)
IoC冯事,(Inverse of Control)控制反轉(zhuǎn),其包含兩個內(nèi)容:其一是控制血公,其二是反轉(zhuǎn)昵仅。在程序中,被調(diào)用類的選擇控制權(quán)從調(diào)用它的類中移除累魔,轉(zhuǎn)交給第三方裁決摔笤。這個第三方指的就是Spring的容器。IoC另解垦写,依賴注入(Dependency Injection)吕世,調(diào)用類對被調(diào)用類的依賴關(guān)系由第三方注入,以移除調(diào)用類對被調(diào)用類的引用梯投。
aop命辖,面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容分蓖。利用AOP可以對業(yè)務(wù)邏輯的各個部分進行隔離尔艇,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性么鹤,同時提高了開發(fā)的效率漓帚。 AOP是OOP的延續(xù),是(Aspect Oriented Programming)的縮寫午磁,意思是面向切面(方面)編程。主要的功能是:日志記錄毡们,性能統(tǒng)計迅皇,安全控制,事務(wù)處理衙熔,異常處理等等登颓。 主要的意圖是:將日志記錄,性能統(tǒng)計红氯,安全控制框咙,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來痢甘,通過對這些行為的分離喇嘱,我們希望可以將它們獨立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進而改 變這些行為的時候不影響業(yè)務(wù)邏輯的代碼塞栅。 作者:佛系的工具人 https://www.bilibili.com/read/cv15072700/ 出處:bilibili
參考文章:https://blog.csdn.net/weixin_43687849/article/details/124257941
https://www.bilibili.com/read/cv15072700/