javascript
这应该是最通俗易懂的一篇Spring知识点总结了
由于Spring家族的東西很多,一次性寫(xiě)完也不太現(xiàn)實(shí)。所以這一次先更新Spring「最核心」的知識(shí)點(diǎn):AOP和IOC
無(wú)論是入門(mén)還是面試,理解AOP和IOC都是非常重要的。在校招的時(shí)候,我沒(méi)被問(wèn)過(guò)Mybatis/Hibernate/Struts2這樣的框架,而Spring就經(jīng)常會(huì)被問(wèn)到。
為什么要用Spring
當(dāng)年的我,剛學(xué)Spring的時(shí)候,會(huì)想:『這IOC和AOP』是什么鬼玩意啊?一大堆的名詞「控制反轉(zhuǎn)」「依賴注入」「面向切面編程」。這是在給我搞笑的吧。
在最開(kāi)始學(xué)的IOC折騰了一大堆的玩意,結(jié)果就是在管「創(chuàng)建對(duì)象」的事??逗我呢???我直接new一個(gè)對(duì)象出來(lái)不香嗎?
有這種想法這種明顯就是「代碼寫(xiě)得少了,想得多了」
我們寫(xiě)代碼,不僅僅是要能實(shí)現(xiàn)功能,實(shí)現(xiàn)完了以后我們還得對(duì)寫(xiě)過(guò)的代碼「維護(hù)」。如果我們的代碼寫(xiě)得很爛,那「維護(hù)」的成本就很高。
維護(hù)實(shí)際上是做什么事?
面對(duì)重復(fù)的/繁瑣的非業(yè)務(wù)代碼:
上一期的「Mybatis」教程也講到了,我們的JDBC寫(xiě)得好好的,運(yùn)行的效率也是杠杠的。但是JDBC需要我們「自行」處理的細(xì)節(jié)太多了,我們需要在里邊添加各種「重復(fù)」的代碼。
我們使用ORM框架,那么我們就可以更加「專(zhuān)注」去實(shí)現(xiàn)本身的業(yè)務(wù),ORM框架把「重復(fù)」的代碼都屏蔽掉,代碼維護(hù)起來(lái)就比JDBC要方便。
Spring IOC 解決的是?對(duì)象管理和對(duì)象依賴的問(wèn)題。
Spring AOP 解決的是?非業(yè)務(wù)代碼抽取的問(wèn)題。
(這里要是沒(méi)基礎(chǔ)的同學(xué),可能看不太懂,下面再來(lái)解釋解釋一下應(yīng)該就沒(méi)問(wèn)題了)
Spring IOC
提到Spring IOC,隨便去網(wǎng)上一搜,我們就可以看到「依賴注入」「控制反轉(zhuǎn)」這兩個(gè)詞。
很多人都會(huì)試圖要把這兩個(gè)詞給解釋清楚,但是太難了,這兩個(gè)詞真的是太難給解釋清楚了。
Spring IOC 解決的是對(duì)象管理和對(duì)象依賴的問(wèn)題。本來(lái)我們的對(duì)象都是new出來(lái)的,而我們?nèi)绻褂肧pring 則把對(duì)象交給「IOC容器」來(lái)管理。
三歪這逼搞事情了?!敢蕾囎⑷搿购汀缚刂品崔D(zhuǎn)」都沒(méi)講,現(xiàn)在還來(lái)了個(gè)「IOC容器」。
「IOC容器」是什么?我們可以理解為是一個(gè)「工廠」,我們把對(duì)象都交由這個(gè)「工廠」來(lái)管理,包括對(duì)象的創(chuàng)建和對(duì)象之間的依賴關(guān)系等等。等我們要用到對(duì)象的時(shí)候,就從這個(gè)「工廠」里邊取出來(lái)。
「控制反轉(zhuǎn)」指的就是:本來(lái)是「由我們自己」new出來(lái)的對(duì)象,現(xiàn)在交給了IOC容器。把這個(gè)對(duì)象的「控制權(quán)」給「他方」了。「控制反轉(zhuǎn)」更多的是一種思想或者說(shuō)是設(shè)計(jì)模式,把原有由自己掌控的事交給「別人」來(lái)處理。
「依賴注入」更多指的是「控制反轉(zhuǎn)」這個(gè)思想的實(shí)現(xiàn)方式:對(duì)象無(wú)需自行創(chuàng)建或管理它們的依賴關(guān)系,依賴關(guān)系將被「自動(dòng)注入」到需要它們的對(duì)象當(dāng)中去。
最簡(jiǎn)單理解「依賴注入」和「控制反轉(zhuǎn)」:本來(lái)我們的對(duì)象都是「由我們自己」new出來(lái)的,現(xiàn)在我們把這個(gè)對(duì)象的創(chuàng)建權(quán)限和對(duì)象之間的依賴關(guān)系交由「IOC容器」來(lái)管理。
悄悄話:我個(gè)人本身是不太喜歡琢磨每個(gè)詞的含義的,很多時(shí)候大佬們也很難解釋清楚。如果是初學(xué)的同學(xué),也不用太糾結(jié)每個(gè)名詞的具體含義,深究下去也沒(méi)有太大的必要。
現(xiàn)在問(wèn)題又來(lái)了,為什么我們要把對(duì)象給「IOC容器」來(lái)管理呢?要理解這個(gè),我建議可以先去看看我寫(xiě)過(guò)的「工廠模式」
理論上,我們可以把「IOC容器」也當(dāng)做是一個(gè)「工廠」,使用IOC的好處就是:
- 將對(duì)象集中統(tǒng)一管理,便于修改
- 降低耦合度(調(diào)用方無(wú)需自己組裝,也無(wú)需關(guān)心對(duì)象的實(shí)現(xiàn),直接從「IOC容器」取就好了)
IOC 需要學(xué)什么?
我們?cè)谑褂肧pring的時(shí)候,首先我們要學(xué)習(xí)的就是怎么把對(duì)象交給「IOC容器管理」
Spring提供了四種方式:
- 注解
- XML
- JavaConfig
- 基于Groovy DSL配置
總的來(lái)說(shuō):我們以XML配置+注解來(lái)裝配Bean比較多,其中注解這種方式占大部分。
把對(duì)象放到「IOC容器」了以后,對(duì)象與對(duì)象之間是有關(guān)系的,我們需要把對(duì)象之間的依賴告訴Spring,讓它來(lái)幫我們解決掉對(duì)象的依賴關(guān)系。
「對(duì)象之間的關(guān)系」別想得太復(fù)雜了。在日常開(kāi)發(fā)中其實(shí)很多時(shí)候就是A對(duì)象里邊有B對(duì)象的屬性而已。
一般來(lái)說(shuō)我們會(huì)通過(guò)構(gòu)造器或者屬性(setting方法)的方式來(lái)注入對(duì)象的依賴
舉個(gè)例子:日常開(kāi)發(fā)中,我們很多時(shí)候用@Component注解標(biāo)識(shí)將對(duì)象放到「IOC容器」中,用@Autowired注解將對(duì)象注入
下面這張圖就很好總結(jié)了以各種方式來(lái)對(duì)Bean的定義和注入。
?
Spring AOP
AOP:Aspect Object Programming 「面向切面編程」,聽(tīng)起來(lái)是不是很牛逼。
Spring AOP主要做的事情就是:「把重復(fù)的代碼抽取,在運(yùn)行的時(shí)候往業(yè)務(wù)方法上動(dòng)態(tài)植入“切面類(lèi)代碼”」
舉個(gè)例子,現(xiàn)在我們有以下的代碼:
上面的代碼其實(shí)最核心的就一行代碼:「保存user對(duì)象到數(shù)據(jù)庫(kù)中」
session.save(user);我們的數(shù)據(jù)庫(kù)表肯定不止user一張表,對(duì)數(shù)據(jù)庫(kù)的增刪改也肯定不止add()方法一個(gè)。所以我們可以想象到:對(duì)數(shù)據(jù)庫(kù)的每次操作,都要寫(xiě)「開(kāi)啟事務(wù)」和「關(guān)閉事務(wù)」這種代碼。
這種代碼對(duì)我們來(lái)說(shuō)是重復(fù)的,于是我們會(huì)想把這種代碼給「抽取」出來(lái)。
如果我們單純用OOP(面向?qū)ο?#xff09;的思想去把代碼給優(yōu)化掉,最終我們的效果可能是這樣的:
即使這樣看起來(lái)代碼已經(jīng)很少了,但我們細(xì)想一下會(huì)發(fā)現(xiàn):update()/delete()方法同樣也會(huì)有aop.begin()這樣的重復(fù)代碼的。
我們想要「消滅」掉這些重復(fù)代碼,可以怎么做?這個(gè)時(shí)候我們應(yīng)該能想到「動(dòng)態(tài)代理」,通過(guò)動(dòng)態(tài)代理,我們可以把對(duì)象「增強(qiáng)」,將非業(yè)務(wù)代碼寫(xiě)在要「增強(qiáng)」的邏輯上。
完了以后,我們就可以通過(guò)「增強(qiáng)后的對(duì)象」去調(diào)用方法,最終屏蔽掉「重復(fù)代碼」
效果可能會(huì)如下:
上面是我們手動(dòng)寫(xiě)的代理來(lái)實(shí)現(xiàn)對(duì)「非業(yè)務(wù)代碼」的抽取,類(lèi)似這樣的場(chǎng)景會(huì)有很多:比如我們要做權(quán)限控制,要對(duì)參數(shù)進(jìn)行校驗(yàn)等等。
Spring 支持了AOP,讓我們可以不用自己「手動(dòng)」去寫(xiě)代理對(duì)象,達(dá)到將「非業(yè)務(wù)代碼」的抽取的效果。
我們可以體驗(yàn)一波Spring AOP是怎么弄的,跟上面的對(duì)比對(duì)比:
效果如下:
總結(jié)
建議:在學(xué)習(xí)IOC之前,可以先看看「工廠模式」。在學(xué)習(xí)AOP之前,可以先看看「代理模式」
理解了「工廠模式」那就知道為什么我們不再直接new對(duì)象,理解了「代理模式」,我們就知道Spring AOP的底層技術(shù)其實(shí)就是「動(dòng)態(tài)代理」,這樣學(xué)習(xí)IOC和AOP的時(shí)候,就會(huì)輕松很多。
還要一點(diǎn)就是不要被「名詞」給嚇唬了,之前不懂某個(gè)技術(shù)的時(shí)候,聽(tīng)別人講一些名詞,我對(duì)此完全不懂。那就可能會(huì)認(rèn)為這個(gè)技術(shù)會(huì)很牛逼,其實(shí)等真正接觸下來(lái),學(xué)習(xí)完了以后,其實(shí)發(fā)現(xiàn)也不過(guò)如此嘛。
總結(jié)
以上是生活随笔為你收集整理的这应该是最通俗易懂的一篇Spring知识点总结了的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: JVM 虚拟机图文详解!真香!秒懂!一点
- 下一篇: 崩溃了,一个HashMap跟面试官扯了半