Spring實戰(zhàn):
以前是學(xué)集成電路的拾积,工作之后成了一枚java程序猿殉挽,記得第一次接觸企業(yè)級應(yīng)用開發(fā)丰涉,對于Spring容器、 bean斯碌、bean的裝配一死、應(yīng)用上下文、依賴注入傻唾、控制反轉(zhuǎn)等等非常核心的概念經(jīng)常是一臉懵逼的狀態(tài)投慈,最近看了Spring實戰(zhàn)講述的兩個Spring核心技術(shù),看的過程中其實還是懵逼的冠骄,不過重復(fù)看了幾遍對概念理解了伪煤,之后發(fā)現(xiàn)以前總是困擾自己的問題已經(jīng)不再是問題,所以寫了這邊文章講一下自己對這些關(guān)鍵詞的理解凛辣,一方面加深自己的理解抱既,另一方面用一個通俗的大白話將自己的理解表述出來希望能幫到一些剛?cè)胄械耐瑢W(xué),希望有所幫助扁誓。
了解某種技術(shù)之前首先要知道它為什么出現(xiàn)防泵,它的出現(xiàn)是為了解決什么問題?-------Spring是為了解決企業(yè)級應(yīng)用開發(fā)的復(fù)雜性即簡化java開發(fā)而創(chuàng)建的蝗敢。
Spring的核心是依賴注入(DI)和面向切面編程(AOP)捷泞。
任何一個有實際意義的應(yīng)用,都會有多個類組成寿谴,這些類相互之間盡心協(xié)作來完成特定的業(yè)務(wù)邏輯肚邢。按照傳統(tǒng)做法,每個對象本身負(fù)責(zé)管理與自身協(xié)作的對象的引用(即他所依賴的類的實例)拭卿,這將導(dǎo)致類與類之間高度耦合和難以測試的代碼骡湖,這種代碼難以復(fù)用,難于理解峻厚,而且典型的會表現(xiàn)出打地鼠是的bug特性响蕴。但另一方面,一定程度上的耦合又是必須的惠桃。通過DI浦夷,對象以及對象之間的依賴關(guān)系完全交由第三方進(jìn)行處理,對象無需自行創(chuàng)建或者管理他們之間的依賴關(guān)系(一般選擇的做法是辜王,如果類A需要依賴類B劈狐,一般將類B實現(xiàn)的接口定義為類A的屬性,這樣做的目的是呐馆,對象只是通過接口(而非具體的類實現(xiàn))來標(biāo)明依賴關(guān)系肥缔,那么這種依賴就能夠在對象本身毫不知情的情況下,用不同的具體實現(xiàn)進(jìn)行替換)汹来。在基于Spring的應(yīng)用中续膳,Spring容器負(fù)責(zé)創(chuàng)建對象改艇,裝配對象、配置并管理他們的整個生命周期坟岔,從生存到死亡谒兄,常見的容器為應(yīng)用上下文(Application Context)。
DI能夠允許相互協(xié)作的軟件組件保持松散耦合社付,而面向切面編程則允許你把遍布應(yīng)用各處的功能分離出來形成可重用的組件承疲。
①看書心得:
大概掃過一些主要內(nèi)容之后,返回來看第一章鸥咖,發(fā)現(xiàn)Spring可以和一個公司的進(jìn)行類比,這個公司包含了所有的職能部門以及各種成熟的規(guī)章制度流程。開發(fā)過程可以理解為公司要開始進(jìn)行運行一個業(yè)務(wù)熙兔,開發(fā)人員就是這個業(yè)務(wù)對應(yīng)的唯一拍板領(lǐng)導(dǎo)住涉,領(lǐng)導(dǎo)不必事無巨細(xì),只需要定義業(yè)務(wù)運行中需要什么樣的人才(bean)(這個過程可能也包含了人與人之間的協(xié)作媳握,類比為你定義的類A依賴類B)蛾找,具體的就可以交公司即Spring進(jìn)行具體的管理打毛,公司不能滿足你的需求時幻枉,領(lǐng)導(dǎo)還可以找外包公司即集成第三方框架來完成任務(wù)诡蜓。
開發(fā)人員--------領(lǐng)導(dǎo)罗珍,leader覆旱;
應(yīng)用上下文------Spring容器的一種扣唱,負(fù)責(zé)bean的創(chuàng)建噪沙,裝配正歼,銷毀等喜爷,類比為秘書或者總經(jīng)理檩帐,assistant湃密;
bean--------------領(lǐng)導(dǎo)定義的具備某種素質(zhì)的員工,其實就是我們定義的類的實例俩由,employee癌蚁;
bean的裝配-----Spring容器負(fù)責(zé)管理的碘梢,協(xié)調(diào)員工和員工之間的協(xié)作伐蒂,類A依賴類B恩沛,秘書直接將符合條件的B類實例指派給A類實例雷客,這個過程開發(fā)人并不需要關(guān)心如何實現(xiàn)搅裙,cooperation部逮;
依賴注入---------就是bean裝配的過程掐禁,即將類B的實例注入類A的過程傅事。
首先對于DI灼芭,Spring中是通過容器(如bean工廠或者應(yīng)用上下文彼绷,前者最簡單寄悯,提供基本的DI支持脆栋,對大多數(shù)應(yīng)用來說比較低級椿争;后者基于beanFactory構(gòu)建,并提供應(yīng)用框架級別的服務(wù)柠逞,如從屬性文件解析文本信息以及發(fā)布用用事件給感興趣的事件監(jiān)聽者板壮,比前者更受歡迎)管理bean的,包括bean的創(chuàng)建、生命周期阱表、銷毀等,應(yīng)用上下文就可以類比為領(lǐng)導(dǎo)的秘書爱致,開發(fā)人員是核心領(lǐng)導(dǎo),每個bean就可以類比為公司中的螺絲釘員工互艾,開發(fā)人員只需要定義需要的類以及類與類之間的依賴關(guān)系好渠,接下來當(dāng)應(yīng)用啟動后假栓,首先加載應(yīng)用上下文也就是公司會先派來一名秘書即Spring容器,然后秘書負(fù)責(zé)創(chuàng)建即招聘來領(lǐng)導(dǎo)需要的每個員工(bean初始化)以及協(xié)調(diào)員工之間的合作拦坠。所以要想實現(xiàn)依賴逐日的功能,就離不開容器,容器是Spring框架實現(xiàn)功能的核心,但是容器的實現(xiàn)有很多中方式链蕊,不唯一,常用的就是應(yīng)用上下文;
當(dāng)員工需要其他員工(Abean中注入beanB-bean的裝配)的時候忱嘹,秘書去按照領(lǐng)要求招聘來的所有員工中尋找有沒有這種符合條件的員工,當(dāng)有的時候直接將這個其他員工指派給前者橱脸,員工是不用關(guān)心他需要的其他員工如何被指派過來础米,這個過程就是裝配bean的過程。開發(fā)人員(即領(lǐng)導(dǎo))負(fù)責(zé)規(guī)劃添诉,即在程序中定義要招聘具備哪些素質(zhì)的員工屁桑,以及他們之間如何協(xié)作(即告訴Spring bean之間的依賴關(guān)系),秘書(Spring容器)負(fù)責(zé)執(zhí)行領(lǐng)導(dǎo)的命令栏赴,即按需求照招聘員工蘑斧,將員工B指派給員工A。若公司里不存在符合條件的員工B就會拋出異常,秘書表示解決不了竖瘾,需要領(lǐng)導(dǎo)上手修改代碼解決問題沟突;或者當(dāng)有多個滿足條件的員工B時,也會拋出異常捕传,秘書表示解決不了惠拭,需要領(lǐng)導(dǎo)修改代碼直到秘書可以唯一確定一個員工B。所有員工會一直被秘書代為管理庸论,直到秘書被撤職职辅;
而對于AOP,可以類比為公司的職能部門聂示,如人力資源域携,法律、后勤等鱼喉,公司給每個員工都需要發(fā)工資涵亏,這不是員工應(yīng)該關(guān)心的工作方面的問題,所以公司將這個交給職能部門去解決蒲凶,領(lǐng)導(dǎo)只要安排好工作气筋,當(dāng)?shù)焦窘Y(jié)算日期(切點),人力資源專員(切面旋圆,即POJO)就會開始結(jié)算需要結(jié)算工資的員工的工資并將工資發(fā)放給員工(結(jié)算和發(fā)放行為就是通知)宠默;
Spring還能通過使用模板消除重復(fù)的樣式代碼,比如集成持久化框架灵巧,這個可以類比為公司的一些審批流程化搀矫,例如員工請假,員工請假本來是需要首先填寫假條刻肄,然后逐次找各級領(lǐng)導(dǎo)審批瓤球,審批完成之后在提交給相關(guān)部門進(jìn)行備份入庫等,其中有一步有問題整個流程都會問題敏弃,這樣太麻煩了卦羡,所以公司將其流程化,員工只需要填寫申請單麦到,其他的重復(fù)流程(如后面的審批提交入庫等)交給公司去做绿饵,員工只需要等待結(jié)果(類比為只需要在代碼中實現(xiàn)必須的邏輯,其他后續(xù)的工作都交給Spring來做)瓶颠,這個過程就消除了重復(fù)的樣板代碼拟赊。
②以下是Spring實戰(zhàn)原文講述的Spring容器中的bean生命周期:
詳細(xì)描述為:
1、Spring對bean進(jìn)行實例化(即創(chuàng)建對象粹淋,對屬性賦值吸祟,初始化方法等)瑟慈;
2、Spring將值和bean的引用注入到bean對應(yīng)的屬性中(bean的裝配)屋匕;
3封豪、如果bean實現(xiàn)了BeanNameAware接口,Spring則將bean的ID傳遞給setBeanName()方法(可類比為給員工一個員工ID)炒瘟;
4吹埠、如果bean實現(xiàn)了BeanFactoryAware接口,Spring將調(diào)用setBeanFactory()方法疮装,將BeanFactory容器實例傳入(現(xiàn)在常用的就是應(yīng)用上下文容器缘琅,Spring初始化容器來管理開發(fā)人員創(chuàng)建的bean);
5廓推、如果bean實現(xiàn)了ApplicationContextAware接口刷袍,Spring將調(diào)用setApplicationContext()方法,將bean所在的應(yīng)用上下文的引用(即應(yīng)用上下文實例)傳入進(jìn)來樊展;
6呻纹、如果bean實現(xiàn)了BeanPostProcessor接口,Spring將調(diào)用他們的postProcessBeforeInitialization()方法(這個目前還不知道是為了干什么)专缠;
7雷酪、如果bean實現(xiàn)了InitializingBean接口,Spring將調(diào)用他們的afterPropertiesSet()方法涝婉,類似的哥力,如果bean使用init-method聲明了初始化方法,該方法也會被調(diào)用墩弯;
8吩跋、如果bean實現(xiàn)了BeanPostProcessor接口,Spring將調(diào)用他們的postProcessAfterInitialization()方法(這個目前還不知道是為了干什么)渔工;
9锌钮、此時bean已經(jīng)準(zhǔn)備就緒,可以被應(yīng)用程序使用了引矩,他們將一直駐留在應(yīng)用上下文中梁丘,直到該應(yīng)用上下文被銷毀;
10脓魏、如果bean實現(xiàn)了DisposableBean接口兰吟,Spring將調(diào)用他的destroy()接口方法通惫。同樣地茂翔,如果bean使用destroy-method聲明了銷毀方法,該方法也會被調(diào)用履腋。
③Spring模塊
Spring發(fā)布版本中包含了很多不同的模塊珊燎,按照功能劃分為6類
就總體而言悔政,這些模塊為企業(yè)級開發(fā)應(yīng)用提供了所需的一切,但是你自己的應(yīng)用是不用引入所有的模塊槽地,只需要根據(jù)自身的需求引入對應(yīng)的功能捌蚊,加入Spring不能滿足需求時近弟,你可以集成第三方框架和類庫祷愉,來實現(xiàn)你要實現(xiàn)的功能。