Spring Boot自學(xué)(十) Spring IOC思想簡述--控制反轉(zhuǎn)(依賴注入)

? ? ? ? 簡單的說,ioc--控制反轉(zhuǎn)溉潭,就是把對象生命周期的管理權(quán)限交給Spring去管理净响。不管是對象的創(chuàng)建還是對象的銷毀少欺,均由Spring去打理

? ? ? ? 對象的創(chuàng)建不再交給程序本身,對象的銷毀也不再是程序本身的責(zé)任馋贤。

我們現(xiàn)在拿一個(gè)小例子講一下赞别,Spring IOC的思想:

首先我們創(chuàng)建一根DAO接口:

public interface UserDao {

void getUser();

}

然后我們創(chuàng)建他的實(shí)現(xiàn)類:

public class UserDaoImplimplements UserDao {

@Override

? ? public void getUser() {

System.out.println("User");

? ? }

}

然后我們寫一個(gè)Service接口:

public interface UserSerevice? {

void getUser();

}

然后將Service接口的實(shí)現(xiàn)類寫出來:

public class UserServiceImplimplements UserSerevice {

private UserDaouserDao=new? UserDaoImplimplements ()? ;

? ? public void setUserDao(UserDao userDao) {

this.userDao = userDao;

? ? }

@Override

? ? public void getUser() {

userDao.getUser();

? ? }

}

我們寫一個(gè)入口程序去創(chuàng)建其對象:

public class Test {

public static void main(String[] args) {

UserServiceImpl service=new UserServiceImpl();

? ? ? ? service.getUser();

? ? }

}

輸出:


大家應(yīng)該可以看到,我在service接口的實(shí)現(xiàn)類里面是直接把Dao這個(gè)實(shí)現(xiàn)類直接在里面new出來了配乓,這樣子的耦合性很強(qiáng)仿滔,不利于后期的修改,所以扰付,我就修改成為這樣子:


然后我們可以創(chuàng)建兩個(gè)Dao實(shí)現(xiàn)類堤撵,但是里面的內(nèi)容你們可以自己修改,這個(gè)我就不一一寫出來了:


程序的入口程序可以這樣寫:

public class Test {

public static void main(String[] args) {

UserServiceImpl userDao =new UserServiceImpl();

? ? ? ? userDao.setUserDao(new UserDaoMySqlImpl());

? ? ? ? userDao.getUser();

? ? ? ? userDao.setUserDao(new UserDaoOracleImpl());

? ? ? ? userDao.getUser();

? ? }

}

然后我們看輸出:


? ? ? ? 我這樣寫羽莺,極大的降低了程序和接口之間的耦合性实昨,方便以后的程序修改,然后我在主程序里面可以分開創(chuàng)建對象盐固,這樣做也方便之后程序的管理荒给。我在setUserDao方法里面寫的是Dao的接口,通過轉(zhuǎn)型刁卜,替換為實(shí)現(xiàn)類志电,進(jìn)一步得到相應(yīng)的實(shí)現(xiàn)功能。

? ? 但是蛔趴,我們使用了Spring以后就不一樣了挑辆,對象的產(chǎn)生和銷毀都交給Spring去統(tǒng)一管理,不再由程序本身去管理孝情。

? ? 我們可以寫一個(gè)小示例試試看:

我們先創(chuàng)建一個(gè)Spring的項(xiàng)目鱼蝉,然后先寫一個(gè)bean類:public class User {

private Stringusername;

? ? private Stringpassword;

? ? public StringgetUsername() {

return username;

? ? }

public void setUsername(String username) {

this.username = username;

? ? }

public StringgetPassword() {

return password;

? ? }

public void setPassword(String password) {

this.password = password;

? ? }

public void UserShow() {

System.out.println("Username:" +username +"\n\n"+"password:" +password);

? ? }

}

然后我們寫一個(gè)xml配置文件:

然后我們寫一個(gè)實(shí)現(xiàn)方法:

public class Test {

public static void main(String[] args) {

ApplicationContext context=new ClassPathXmlApplicationContext("com/spring/demo/controller/user.xml");

? ? ? ? User user = (User) context.getBean("user");

? ? ? ? user.UserShow();

? ? }

}

注意,路徑問題箫荡,我寫的是我的包名加上文件名魁亦,因?yàn)槲野蓌ml文件放在我的同目錄寫,所有我這樣寫羔挡,如果你們是maven項(xiàng)目洁奈,你們把包名路徑換成classpath:就好了,如果是java項(xiàng)目绞灼,你們寫WEB-INF/+文件名就好了

然后我們點(diǎn)擊運(yùn)行利术,我們看看結(jié)果:


Look,我們是不是沒有創(chuàng)建對象啊低矮,但是你肯定會說印叁,是真的創(chuàng)建對象了嗎,那我們在bean類的構(gòu)造方法里面寫一個(gè)隊(duì)友的輸出:


點(diǎn)擊運(yùn)行:


你看,是不是創(chuàng)建對象了

? ? ? ? Spring就是這樣子喉钢,我們不需要再去按照老樣子自己在程序里面創(chuàng)建對象,銷毀對象良姆。一切的對象管理都交給Spring去做肠虽,告訴他,我什么時(shí)候需要創(chuàng)建對象了玛追,我什么時(shí)候要加入什么值税课。對象的管理權(quán)交給了Spring,我們不需要去管理痊剖。

? ? ? ? 簡單粗俗一點(diǎn)說韩玩,好比你爸爸的工資使用權(quán)不再是你爸爸的,這個(gè)使用權(quán)都給你老媽了陆馁,你爸爸沒有權(quán)利去管理自己的工資找颓。

然后我們現(xiàn)在總結(jié):

第一點(diǎn):什么是IOC:

IoC 容器:最主要是完成了完成對象的創(chuàng)建和依賴的管理注入等等。

先從我們自己設(shè)計(jì)這樣一個(gè)視角來考慮:

所謂控制反轉(zhuǎn)叮贩,就是把原先我們代碼里面需要實(shí)現(xiàn)的對象創(chuàng)建击狮、依賴的代碼,反轉(zhuǎn)給容器來幫忙實(shí)現(xiàn)益老。那么必然的我們需要創(chuàng)建一個(gè)容器彪蓬,同時(shí)需要一種描述來讓容器知道需要創(chuàng)建的對象與對象的關(guān)系。這個(gè)描述最具體表現(xiàn)就是我們可配置的文件捺萌。

對象和對象關(guān)系怎么表示档冬?

可以用 xml , properties 文件等語義化配置文件表示桃纯。

描述對象關(guān)系的文件存放在哪里酷誓?

可能是 classpath , filesystem 慈参,或者是 URL 網(wǎng)絡(luò)資源呛牲, servletContext 等。

回到正題驮配,有了配置文件娘扩,還需要對配置文件解析。

不同的配置文件對對象的描述不一樣壮锻,如標(biāo)準(zhǔn)的琐旁,自定義聲明式的,如何統(tǒng)一猜绣? 在內(nèi)部需要有一個(gè)統(tǒng)一的關(guān)于對象的定義灰殴,所有外部的描述都必須轉(zhuǎn)化成統(tǒng)一的描述定義。

如何對不同的配置文件進(jìn)行解析掰邢?需要對不同的配置文件語法牺陶,采用不同的解析器

第二點(diǎn): Spring IOC體系結(jié)構(gòu)

(1) BeanFactory

? ? ? ? Spring Bean的創(chuàng)建是典型的工廠模式伟阔,這一系列的Bean工廠,也即IOC容器為開發(fā)者管理對象間的依賴關(guān)系提供了很多便利和基礎(chǔ)服務(wù)掰伸,在Spring中有許多的IOC容器的實(shí)現(xiàn)供用戶選擇和使用皱炉,其相互關(guān)系如下:


? ? ? ? 其中BeanFactory作為最頂層的一個(gè)接口類,它定義了IOC容器的基本功能規(guī)范狮鸭,BeanFactory 有三個(gè)子類:ListableBeanFactory合搅、HierarchicalBeanFactory 和AutowireCapableBeanFactory。但是從上圖中我們可以發(fā)現(xiàn)最終的默認(rèn)實(shí)現(xiàn)類是 DefaultListableBeanFactory歧蕉,他實(shí)現(xiàn)了所有的接口灾部。那為何要定義這么多層次的接口呢?查閱這些接口的源碼和說明發(fā)現(xiàn)惯退,每個(gè)接口都有他使用的場合赌髓,它主要是為了區(qū)分在 Spring 內(nèi)部在操作過程中對象的傳遞和轉(zhuǎn)化過程中,對對象的數(shù)據(jù)訪問所做的限制蒸痹。例如 ListableBeanFactory 接口表示這些 Bean 是可列表的春弥,而 HierarchicalBeanFactory 表示的是這些 Bean 是有繼承關(guān)系的,也就是每個(gè)Bean 有可能有父 Bean叠荠。? ? ? ?

? ? ? ? ? ? AutowireCapableBeanFactory 接口定義 Bean 的自動裝配規(guī)則匿沛。這四個(gè)接口共同定義了 Bean 的集合、Bean 之間的關(guān)系榛鼎、以及 Bean 行為.

? ? ? ? 在BeanFactory里只對IOC容器的基本行為作了定義逃呼,根本不關(guān)心你的bean是如何定義怎樣加載的。正如我們只關(guān)心工廠里得到什么的產(chǎn)品對象者娱,至于工廠是怎么生產(chǎn)這些對象的抡笼,這個(gè)基本的接口不關(guān)心。

? ? ? ? ? ? 而要知道工廠是如何產(chǎn)生對象的黄鳍,我們需要看具體的IOC容器實(shí)現(xiàn)推姻,spring提供了許多IOC容器的實(shí)現(xiàn)。比如XmlBeanFactory框沟,ClasspathXmlApplicationContext等藏古。其中XmlBeanFactory就是針對最基本的ioc容器的實(shí)現(xiàn),這個(gè)IOC容器可以讀取XML文件定義的BeanDefinition(XML文件中對bean的描述),如果說XmlBeanFactory是容器中的屌絲忍燥,ApplicationContext應(yīng)該算容器中的高帥富.

? ? ? ? ? ? ApplicationContext是Spring提供的一個(gè)高級的IoC容器拧晕,它除了能夠提供IoC容器的基本功能外,還為用戶提供了以下的附加服務(wù)梅垄。

從ApplicationContext接口的實(shí)現(xiàn)厂捞,我們看出其特點(diǎn):

? ? ? ? 1.? 支持信息源,可以實(shí)現(xiàn)國際化。(實(shí)現(xiàn)MessageSource接口)

? ? ? ? 2.? 訪問資源靡馁。(實(shí)現(xiàn)ResourcePatternResolver接口欲鹏,這個(gè)后面要講)

? ? ? ? 3.? 支持應(yīng)用事件。(實(shí)現(xiàn)ApplicationEventPublisher接口)

(2) BeanDefinition

? ? ? ? SpringIOC容器管理了我們定義的各種Bean對象及其相互的關(guān)系臭墨,Bean對象在Spring實(shí)現(xiàn)中是以BeanDefinition來描述的貌虾,其繼承體系如下:

? ? ? ? Bean 的解析過程非常復(fù)雜,功能被分的很細(xì)裙犹,因?yàn)檫@里需要被擴(kuò)展的地方很多,必須保證有足夠的靈活性衔憨,以應(yīng)對可能的變化叶圃。Bean 的解析主要就是對 Spring 配置文件的解析。這個(gè)解析過程主要通過下圖中的類完成:

Spring IOC控制反轉(zhuǎn)践图,我就基本介紹到這里掺冠,個(gè)人見解,如果有什么不對的地方码党,請指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末德崭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子揖盘,更是在濱河造成了極大的恐慌眉厨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兽狭,死亡現(xiàn)場離奇詭異憾股,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)箕慧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門服球,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颠焦,你說我怎么就攤上這事斩熊。” “怎么了伐庭?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵粉渠,是天一觀的道長。 經(jīng)常有香客問我似忧,道長渣叛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任盯捌,我火速辦了婚禮淳衙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己箫攀,他們只是感情好肠牲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般循诉。 火紅的嫁衣襯著肌膚如雪紧显。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天肥印,我揣著相機(jī)與錄音,去河邊找鬼绝葡。 笑死深碱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的藏畅。 我是一名探鬼主播敷硅,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼愉阎!你這毒婦竟也來了绞蹦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤榜旦,失蹤者是張志新(化名)和其女友劉穎幽七,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溅呢,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锉走,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藕届。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挪蹭。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖休偶,靈堂內(nèi)的尸體忽然破棺而出梁厉,到底是詐尸還是另有隱情,我是刑警寧澤踏兜,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布词顾,位于F島的核電站,受9級特大地震影響碱妆,放射性物質(zhì)發(fā)生泄漏肉盹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一疹尾、第九天 我趴在偏房一處隱蔽的房頂上張望上忍。 院中可真熱鬧骤肛,春花似錦、人聲如沸窍蓝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吓笙。三九已至淑玫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間面睛,已是汗流浹背絮蒿。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叁鉴,地道東北人歌径。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像亲茅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子狗准,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理克锣,服務(wù)發(fā)現(xiàn),斷路器腔长,智...
    卡卡羅2017閱讀 134,633評論 18 139
  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器袭祟,...
    simoscode閱讀 6,702評論 2 22
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法捞附,內(nèi)部類的語法巾乳,繼承相關(guān)的語法,異常的語法鸟召,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • 來源:關(guān)于Spring IOC (DI-依賴注入)你需要知道的一切作者:zejian Dao層(AccountDa...
    楊井閱讀 5,328評論 0 27
  • 一片蔥綠的心形葉子悠悠飄落下來,落在我匆匆行走的路邊跟继。那時(shí)种冬,步履匆匆的我還沉浸在盛夏美麗的景致里。 不曉得從什么時(shí)...
    雪漫飛閱讀 325評論 2 7