欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring的IOC原理詳情

 更新時間:2022年07月08日 17:18:25   作者:向著百萬年薪努力的小趙  
這篇文章主要介紹了Spring的IOC原理詳情,IOC是Inversion?of?Control的縮寫,多數(shù)書籍翻譯成“控制反轉(zhuǎn)”,還有些書籍翻譯成為控制反向或者控制倒置

1 IOC的理論背景

我們都知道,在采用面向?qū)ο蠓椒ㄔO(shè)計的軟件系統(tǒng)中,它的底層實現(xiàn)都是由N個對象組成的,所有的對象通過彼此的合作,最終實現(xiàn)系統(tǒng)的業(yè)務(wù)邏輯。

如果我們打開機械式手表的后蓋,就會看到與上面類似的情形,各個齒輪分別帶動時針、分針和秒針順時針旋轉(zhuǎn),從而在表盤上產(chǎn)生正確的時間。

圖中描述的就是這樣的一個齒輪組,它擁有多個獨立的齒輪,這些齒輪相互嚙合在一起,協(xié)同工作,共同完成某項任務(wù)。我們可以看到,在這樣的齒輪組中,如果有一個齒輪出了問題,就可能會影響到整個齒輪組的正常運轉(zhuǎn)。

齒輪組中齒輪之間的嚙合關(guān)系,與軟件系統(tǒng)中對象之間的耦合關(guān)系非常相似。對象之間的耦合關(guān)系是無法避免的,也是必要的,這是協(xié)同工作的基礎(chǔ)。
現(xiàn)在,伴隨著工業(yè)級應(yīng)用的規(guī)模越來越龐大,對象之間的依賴關(guān)系也越來越復(fù)雜,經(jīng)常會出現(xiàn)對象之間的多重依賴性關(guān)系,因此,架構(gòu)師和設(shè)計師對于系統(tǒng)的分析和設(shè)計,將面臨更大的挑戰(zhàn)。

對象之間耦合度過高的系統(tǒng),必然會出現(xiàn)牽一發(fā)而動全身的情形

耦合關(guān)系不僅會出現(xiàn)在對象與對象之間,也會出現(xiàn)在軟件系統(tǒng)的各模塊之間,以及軟件系統(tǒng)和硬件系統(tǒng)之間。
如何降低系統(tǒng)之間、模塊之間和對象之間的耦合度,是軟件工程永遠追求的目標之一。

為了解決對象之間的耦合度過高的問題,軟件專家Michael Mattson提出了IOC理論,用來實現(xiàn)對象之間的“解耦”,目前這個理論已經(jīng)被成功地應(yīng)用到實踐當中,很多的J2EE項目均采用了IOC框架產(chǎn)品Spring。

2 什么是控制反轉(zhuǎn)(IoC)

IOC是Inversion of Control的縮寫,多數(shù)書籍翻譯成“控制反轉(zhuǎn)”,還有些書籍翻譯成為“控制反向”或者“控制倒置”。

1996年,Michael Mattson在一篇有關(guān)探討面向?qū)ο罂蚣艿奈恼轮?,首先提出了IOC 這個概念。

簡單來說就是把復(fù)雜系統(tǒng)分解成相互合作的對象,這些對象類通過封裝以后,內(nèi)部實現(xiàn)對外部是透明的,從而降低了解決問題的復(fù)雜度,而且可以靈活地被重用和擴展。

IOC理論提出的觀點大體是這樣的:借助于“第三方”實現(xiàn)具有依賴關(guān)系的對象之間的解耦,

如下圖:

由于引進了中間位置的“第三方”,也就是IOC容器,使得A、B、C、D這4個對象沒有了耦合關(guān)系,齒輪之間的傳動全部依靠“第三方”了,全部對象的控制權(quán)全部上繳給“第三方”IOC容器,所以,IOC容器成了整個系統(tǒng)的關(guān)鍵核心,它起到了一種類似“粘合劑”的作用,把系統(tǒng)中的所有對象粘合在一起發(fā)揮作用,如果沒有這個“粘合劑”,對象與對象之間會彼此失去聯(lián)系,這就是有人把IOC容器比喻成“粘合劑”的由來。

我們再來做個試驗:把上圖中間的IOC容器拿掉,然后再來看看這套系統(tǒng):

我們現(xiàn)在看到的畫面,就是我們要實現(xiàn)整個系統(tǒng)所需要完成的全部內(nèi)容。這時候,A、B、C、D這4個對象之間已經(jīng)沒有了耦合關(guān)系,彼此毫無聯(lián)系,這樣的話,當你在實現(xiàn)A的時候,根本無須再去考慮B、C和D了,對象之間的依賴關(guān)系已經(jīng)降低到了最低程度。所以,如果真能實現(xiàn)IOC容器,對于系統(tǒng)開發(fā)而言,這將是一件多么美好的事情,參與開發(fā)的每一成員只要實現(xiàn)自己的類就可以了,跟別人沒有任何關(guān)系!

軟件系統(tǒng)在沒有引入IOC容器之前,如圖1所示,對象A依賴于對象B,那么對象A在初始化或者運行到某一點的時候,自己必須主動去創(chuàng)建對象B或者使用已經(jīng)創(chuàng)建的對象B。無論是創(chuàng)建還是使用對象B,控制權(quán)都在自己手上。
  軟件系統(tǒng)在引入IOC容器之后,這種情形就完全改變了,如圖3所示,由于IOC容器的加入,對象A與對象B之間失去了直接聯(lián)系,所以,當對象A運行到需要對象B的時候,IOC容器會主動創(chuàng)建一個對象B注入到對象A需要的地方。

通過前后的對比,我們不難看出來:對象A獲得依賴對象B的過程,由主動行為變?yōu)榱吮粍有袨?,控制?quán)顛倒過來了,這就是“控制反轉(zhuǎn)”這個名稱的由來。

3 IOC的別名:依賴注入(DI)

2004年,Martin Fowler探討了同一個問題,既然IOC是控制反轉(zhuǎn),那么到底是“哪些方面的控制被反轉(zhuǎn)了呢?”
經(jīng)過詳細地分析和論證后,他得出了答案:“獲得依賴對象的過程被反轉(zhuǎn)了”。控制被反轉(zhuǎn)之后,獲得依賴對象的過程由自身管理變?yōu)榱擞蒊OC容器主動注入。于是,他給“控制反轉(zhuǎn)”取了一個更合適的名字叫做“依賴注入(Dependency Injection)”。他的這個答案,實際上給出了實現(xiàn)IOC的方法:注入。

所謂依賴注入,就是由IOC容器在運行期間,動態(tài)地將某種依賴關(guān)系注入到對象之中。

所以,依賴注入(DI)和控制反轉(zhuǎn)(IOC)是從不同的角度的描述的同一件事情,就是指通過引入IOC容器,利用依賴關(guān)系注入的方式,實現(xiàn)對象之間的解耦。

我們舉一個生活中的例子,來幫助理解依賴注入的過程。大家對USB接口和USB設(shè)備應(yīng)該都很熟悉吧,USB為我們使用電腦提供了很大的方便,現(xiàn)在有很多的外部設(shè)備都支持USB接口。

現(xiàn)在,我們利用電腦主機和USB接口來實現(xiàn)一個任務(wù):從外部USB設(shè)備讀取一個文件。
電腦主機讀取文件的時候,它一點也不會關(guān)心USB接口上連接的是什么外部設(shè)備,而且它確實也無須知道。它的任務(wù)就是讀取USB接口,掛接的外部設(shè)備只要符合USB接口標準即可。

所以,如果我給電腦主機連接上一個U盤,那么主機就從U盤上讀取文件;如果我給電腦主機連接上一個外置硬盤,那么電腦主機就從外置硬盤上讀取文件。

掛接外部設(shè)備的權(quán)力由我作主,即控制權(quán)歸我,至于USB接口掛接的是什么設(shè)備,電腦主機是決定不了,它只能被動的接受。
電腦主機需要外部設(shè)備的時候,根本不用它告訴我,我就會主動幫它掛上它想要的外部設(shè)備,你看我的服務(wù)是多么的到位。這就是我們生活中常見的一個依賴注入的例子。在這個過程中,我就起到了IOC容器的作用。

通過這個例子,依賴注入的思路已經(jīng)非常清楚:當電腦主機讀取文件的時候,我就把它所要依賴的外部設(shè)備,幫他掛接上。整個外部設(shè)備注入的過程和一個被依賴的對象在系統(tǒng)運行時被注入另外一個對象內(nèi)部的過程完全一樣。
我們把依賴注入應(yīng)用到軟件系統(tǒng)中,再來描述一下這個過程:

對象A依賴于對象B,當對象 A需要用到對象B的時候,IOC容器就會立即創(chuàng)建一個對象B送給對象A。IOC容器就是一個對象制造工廠,你需要什么,它會給你送去,你直接使用就行了,而再也不用去關(guān)心你所用的東西是如何制成的,也不用關(guān)心最后是怎么被銷毀的,這一切全部由IOC容器包辦。
在傳統(tǒng)的實現(xiàn)中,由程序內(nèi)部代碼來控制組件之間的關(guān)系。我們經(jīng)常使用new關(guān)鍵字來實現(xiàn)兩個組件之間關(guān)系的組合,這種實現(xiàn)方式會造成組件之間耦合。IOC很好地解決了該問題,它將實現(xiàn)組件間關(guān)系從程序內(nèi)部提到外部容器,也就是說由容器在運行期將組件間的某種依賴關(guān)系動態(tài)注入組件中。

4 IOC為我們帶來了什么好處

我們還是從USB的例子說起,使用USB外部設(shè)備比使用內(nèi)置硬盤,到底帶來什么好處?

  • 第一、USB設(shè)備作為電腦主機的外部設(shè)備,在插入主機之前,與電腦主機沒有任何的關(guān)系,只有被我們連接在一起之后,兩者才發(fā)生聯(lián)系,具有相關(guān)性。所以,無論兩者中的任何一方出現(xiàn)什么的問題,都不會影響另一方的運行。這種特性體現(xiàn)在軟件工程中,就是可維護性比較好,非常便于進行單元測試,便于調(diào)試程序和診斷故障。代碼中的每一個Class都可以單獨測試,彼此之間互不影響,只要保證自身的功能無誤即可,這就是組件之間低耦合或者無耦合帶來的好處。
  • 第二、USB設(shè)備和電腦主機的之間無關(guān)性,還帶來了另外一個好處,生產(chǎn)USB設(shè)備的廠商和生產(chǎn)電腦主機的廠商完全可以是互不相干的人,各干各事,他們之間唯一需要遵守的就是USB接口標準。這種特性體現(xiàn)在軟件開發(fā)過程中,好處可是太大了。每個開發(fā)團隊的成員都只需要關(guān)心實現(xiàn)自身的業(yè)務(wù)邏輯,完全不用去關(guān)心其它的人工作進展,因為你的任務(wù)跟別人沒有任何關(guān)系,你的任務(wù)可以單獨測試,你的任務(wù)也不用依賴于別人的組件,再也不用扯不清責(zé)任了。所以,在一個大中型項目中,團隊成員分工明確、責(zé)任明晰,很容易將一個大的任務(wù)劃分為細小的任務(wù),開發(fā)效率和產(chǎn)品質(zhì)量必將得到大幅度的提高。
  • 第三、同一個USB外部設(shè)備可以插接到任何支持USB的設(shè)備,可以插接到電腦主機,也可以插接到DV機,USB外部設(shè)備可以被反復(fù)利用。在軟件工程中,這種特性就是可復(fù)用性好,我們可以把具有普遍性的常用組件獨立出來,反復(fù)利用到項目中的其它部分,或者是其它項目,當然這也是面向?qū)ο蟮幕咎卣?。顯然,IOC不僅更好地貫徹了這個原則,提高了模塊的可復(fù)用性。符合接口標準的實現(xiàn),都可以插接到支持此標準的模塊中。
  • 第四、同USB外部設(shè)備一樣,模塊具有熱插拔特性。IOC生成對象的方式轉(zhuǎn)為外置方式,也就是把對象生成放在配置文件里進行定義,這樣,當我們更換一個實現(xiàn)子類將會變得很簡單,只要修改配置文件就可以了,完全具有熱插撥的特性。

以上幾點好處,難道還不足以打動我們,讓我們在項目開發(fā)過程中使用IOC框架嗎?

5 IOC容器的技術(shù)剖析

IOC中最基本的技術(shù)就是“反射(Reflection)”編程,目前.Net C#、Java和PHP5等語言均支持,其中PHP5的技術(shù)書籍中,有時候也被翻譯成“映射”。有關(guān)反射的概念和用法,大家應(yīng)該都很清楚,通俗來講就是根據(jù)給出的類名(字符串方式)來動態(tài)地生成對象。

這種編程方式可以讓對象在生成時才決定到底是哪一種對象。反射的應(yīng)用是很廣泛的,很多的成熟的框架,比如象Java中的Hibernate、Spring框架,.Net中 NHibernate、Spring.Net框架都是把“反射”做為最基本的技術(shù)手段。
反射技術(shù)其實很早就出現(xiàn)了,但一直被忽略,沒有被進一步的利用。當時的反射編程方式相對于正常的對象生成方式要慢至少得10倍。現(xiàn)在的反射技術(shù)經(jīng)過改良優(yōu)化,已經(jīng)非常成熟,反射方式生成對象和通常對象生成方式,速度已經(jīng)相差不大了,大約為1-2倍的差距。

我們可以把IOC容器的工作模式看做是工廠模式的升華,可以把IOC容器看作是一個工廠,這個工廠里要生產(chǎn)的對象都在配置文件中給出定義,然后利用編程語言的的反射編程,根據(jù)配置文件中給出的類名生成相應(yīng)的對象。從實現(xiàn)來看,IOC是把以前在工廠方法里寫死的對象生成代碼,改變?yōu)橛膳渲梦募矶x,也就是把工廠和對象生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。

6 IOC容器的一些產(chǎn)品

Sun ONE技術(shù)體系下的IOC容器有:

  輕量級的有Spring、Guice、Pico Container、Avalon、HiveMind;
  重量級的有EJB;
  不輕不重的有JBoss,Jdon等等。
Spring框架作為Java開發(fā)中最流行的框架之一,大中小項目中都有使用,非常成熟,應(yīng)用廣泛,EJB在關(guān)鍵性的工業(yè)級項目中也被使用,比如某些電信業(yè)務(wù)。
.Net技術(shù)體系下的IOC容器有:Spring.Net、Castle等等。
Spring.Net是從Java的Spring移植過來的IOC容器,Castle的IOC容器就是Windsor部分。它們均是輕量級的框架,比較成熟,其中Spring.Net已經(jīng)被逐漸應(yīng)用于各種項目中。

7 使用IOC框架應(yīng)該注意什么

使用IOC框架產(chǎn)品能夠給我們的開發(fā)過程帶來很大的好處,但是也要充分認識引入IOC框架的缺點,做到心中有數(shù),杜絕濫用框架。

  • 第一、軟件系統(tǒng)中由于引入了第三方IOC容器,生成對象的步驟變得有些復(fù)雜,本來是兩者之間的事情,又憑空多出一道手續(xù),所以,我們在剛開始使用IOC框架的時候,會感覺系統(tǒng)變得不太直觀。所以,引入了一個全新的框架,就會增加團隊成員學(xué)習(xí)和認識的培訓(xùn)成本,并且在以后的運行維護中,還得讓新加入者具備同樣的知識體系。
  • 第二、由于IOC容器生成對象是通過反射方式,在運行效率上有一定的損耗。如果你要追求運行效率的話,就必須對此進行權(quán)衡。
  • 第三、具體到IOC框架產(chǎn)品(比如:Spring)來講,需要進行大量的配制工作,比較繁瑣,對于一些小的項目而言,客觀上也可能加大一些工作成本。
  • 第四、IOC框架產(chǎn)品本身的成熟度需要進行評估,如果引入一個不成熟的IOC框架產(chǎn)品,那么會影響到整個項目,所以這也是一個隱性的風(fēng)險。

到此這篇關(guān)于Spring的IOC原理詳情的文章就介紹到這了,更多相關(guān)Spring IOC 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Socket通信(一)之客戶端程序 發(fā)送和接收數(shù)據(jù)

    Java Socket通信(一)之客戶端程序 發(fā)送和接收數(shù)據(jù)

    對于Socket通信簡述,服務(wù)端往Socket的輸出流里面寫東西,客戶端就可以通過Socket的輸入流讀取對應(yīng)的內(nèi)容,Socket與Socket之間是雙向連通的,所以客戶端也可以往對應(yīng)的Socket輸出流里面寫東西,然后服務(wù)端對應(yīng)的Socket的輸入流就可以讀出對應(yīng)的內(nèi)容
    2016-03-03
  • 開發(fā)者在Idea 中常見的配置,你都了解嗎

    開發(fā)者在Idea 中常見的配置,你都了解嗎

    idea這款java開發(fā)工具真是好用無比,不僅好用而且界面也很好看,有黑白主題,功能強大配置簡單,好了不多說了,今天給大家羅列下Idea 中常見的配置,喜歡的朋友一起看看吧
    2021-06-06
  • SpringCloud之監(jiān)控數(shù)據(jù)聚合Turbine的實現(xiàn)

    SpringCloud之監(jiān)控數(shù)據(jù)聚合Turbine的實現(xiàn)

    這篇文章主要介紹了SpringCloud之監(jiān)控數(shù)據(jù)聚合Turbine的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • java實現(xiàn)單詞搜索迷宮游戲

    java實現(xiàn)單詞搜索迷宮游戲

    這篇文章主要介紹了java實現(xiàn)單詞搜索迷宮游戲,實例分析了迷宮游戲的實現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • 深入講解SPI?在?Spring?中的應(yīng)用

    深入講解SPI?在?Spring?中的應(yīng)用

    這篇文章主要介紹了深入講解SPI在Spring中的應(yīng)用,SPI是Java內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機制,可以用來提高框架的擴展性,主要用于框架的開發(fā)中
    2022-06-06
  • idea項目文件夾橫向顯示,縱向顯示的解決方法

    idea項目文件夾橫向顯示,縱向顯示的解決方法

    這篇文章主要介紹了idea項目文件夾橫向顯示,縱向顯示的解決方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • jetbrain?fleet對標vscode實際操作

    jetbrain?fleet對標vscode實際操作

    Gradle是一個基于Apache Ant和Apache Maven概念項目自動化構(gòu)建開源工具,jetbrain家的fleet(已獲得預(yù)覽權(quán)限)直接對標vscode?,?fleet有望超過vscode嗎?今天我們實際操作下
    2021-12-12
  • 淺談java 中equals和==的區(qū)別

    淺談java 中equals和==的區(qū)別

    這篇文章主要介紹了java 中equals和==的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Apache Commons Math3探索之快速傅立葉變換代碼示例

    Apache Commons Math3探索之快速傅立葉變換代碼示例

    這篇文章主要介紹了Apache Commons Math3探索之快速傅立葉變換代碼示例,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • SpringBoot中@Import注解如何正確使用

    SpringBoot中@Import注解如何正確使用

    這篇文章主要介紹了SpringBoot中@Import注解的使用方式,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-06-06

最新評論