Spring IOC容器

一、IOC收叶,inversion of control骄呼,控制反轉(zhuǎn)

1. 如何理解IOC

以前對(duì)象的創(chuàng)建由程序員控制,什么時(shí)候創(chuàng)建判没,用哪個(gè)構(gòu)造函數(shù)蜓萄;控制反轉(zhuǎn)把控制權(quán)交給容器。Spring通過(guò)DI實(shí)現(xiàn)控制反轉(zhuǎn)澄峰。把Spring IoC容器比作一間餐館嫉沽,來(lái)到餐館時(shí)直接招呼服務(wù)員:點(diǎn)菜!并不關(guān)心菜的原料是什么俏竞、如何把菜做出來(lái)绸硕。IoC容器也一樣,你只需要告訴它需要某個(gè)bean魂毁,它就把對(duì)應(yīng)的實(shí)例扔給你玻佩,無(wú)需關(guān)心bean是否依賴(lài)其他組件、如何初始化席楚。

就像做菜需要菜譜和原材料咬崔,容器也需要記錄各個(gè)對(duì)象以及依賴(lài)關(guān)系;BeanDefinition記錄該信息烦秩;每個(gè)bean都有對(duì)應(yīng)的BeanDefinition垮斯,保存包括class類(lèi)型、是否是抽象類(lèi)只祠、構(gòu)造方法和參數(shù)兜蠕、其它屬性等信息。向容器請(qǐng)求對(duì)象時(shí)抛寝,容器基于beanDefinition利用反射機(jī)制構(gòu)建bean實(shí)例并返回牺氨。

BeanFactory和BeanDefinitionRegistry接口基于BeanDefinition完成bean的創(chuàng)建和管理狡耻,就像餐館上菜的過(guò)程。BeanFactory包含getBean等管理bean的方法猴凹,BeanDefinitionRegistry包含 registerBeanDefinition夷狰、removeBeanDefinition、getBeanDefinition等管理BeanDefinition的方法郊霎。簡(jiǎn)單來(lái)說(shuō)沼头,bean管理就是創(chuàng)建beanDefinition并放入beanRegistry,使用bean的時(shí)候則調(diào)用beanFactory的getBean方法獲得bean實(shí)例书劝。

容器的工作分為容器啟動(dòng)階段與bean實(shí)例化階段进倍;前者通過(guò)xml、注解加載bean的定義购对,構(gòu)造為beanDefinition并放到BeanRegistry猾昆。后者在調(diào)用getBean或由于bean的依賴(lài)關(guān)系需要隱式調(diào)用getBean時(shí)觸發(fā),容器檢查該bean是否實(shí)例化完成骡苞,完成則返回bean垂蜗,否則根據(jù)beanDefinition進(jìn)行初始化并返回。

我們通常使用的容器ApplicationContext解幽,構(gòu)建在BeanFactory之上贴见,除了具有BeanFactory的能力外,還提供其他支持等躲株。它在容器啟動(dòng)時(shí)全部完成所有bean的初始化和依賴(lài)注入操作片部。

2. 依賴(lài)注入DI

DI已經(jīng)成為一個(gè)設(shè)計(jì)模式理念,讓代碼變得容易理解和測(cè)試霜定。傳統(tǒng)的做法是每個(gè)對(duì)象負(fù)責(zé)管理與自己協(xié)作的對(duì)象引用档悠。DI的做法是由第三方(容器)負(fù)責(zé)管理對(duì)象的依賴(lài)關(guān)系,對(duì)象無(wú)需自行創(chuàng)建或者管理他們的依賴(lài)關(guān)系望浩。

DI帶來(lái)的最大收益就是松耦合站粟。如果一個(gè)對(duì)象只通過(guò)接口來(lái)表明依賴(lài)關(guān)系,這種依賴(lài)就能在對(duì)象本身毫不知情的情況下曾雕,用不同的具體實(shí)現(xiàn)進(jìn)行替換奴烙。這是是面向接口編程的好處。對(duì)依賴(lài)進(jìn)行替換的最常用方法就是在測(cè)試的時(shí)候是用mock來(lái)實(shí)現(xiàn)剖张。

3. 特殊情形

日常編碼中可能會(huì)用到beanFactory的情形:BeanFactory可以動(dòng)態(tài)的往spring容器中注入bean切诀;假設(shè)我一個(gè)bean最開(kāi)始不要求被spring實(shí)例化,在某個(gè)時(shí)機(jī)需要自己實(shí)例化搔弄,實(shí)例化好之后通過(guò)BeanFactory添加到spring容器當(dāng)中:applicationContext.getBeanFactory().registerSingleton("bname",你的對(duì)象);

如何在工具類(lèi)中使用bean幅虑?首先spring的DI限于在bean中進(jìn)行依賴(lài)注入,進(jìn)行bean的裝配顾犹;其次倒庵,工具類(lèi)通常不是bean褒墨,我們通常會(huì)使用其靜態(tài)方法,而無(wú)需對(duì)工具類(lèi)進(jìn)行實(shí)例化擎宝;第三郁妈,非bean的類(lèi)中使用其他bean可以通過(guò)applicationContext.getBean("beanName")的方式。

如果有多個(gè)bean可以注入如何選擇绍申,autowired首先選擇類(lèi)型一致的bean噩咪,如果有多個(gè)類(lèi)型一致的bean則進(jìn)一步使用qualifier通過(guò)bean的名字進(jìn)行選擇。但是現(xiàn)在好像已經(jīng)不流行autowired了极阅。(Q)

二胃碾、bean

1. bean的作用域scope

spring支持6種作用域,并支持自定義作用域筋搏,默認(rèn)為singleton仆百。prototype;request表示每個(gè)請(qǐng)求創(chuàng)建一個(gè)實(shí)例奔脐;session是在一個(gè)會(huì)話周期內(nèi)有一個(gè)實(shí)例俄周;application是指在一個(gè)servletContext中只有一個(gè)實(shí)例;此外還有websocket帖族。prototype為多例模式栈源,即每次從beanFactory獲取bean都會(huì)創(chuàng)建一個(gè)新的bean挡爵。

1.1 單例

在Spring出現(xiàn)之前竖般,我們需要用到某個(gè)實(shí)例就需要自己去調(diào)用構(gòu)造函數(shù)把它構(gòu)造出來(lái),如果我們需要在多個(gè)地方使用該實(shí)例茶鹃,要么多次構(gòu)造涣雕,要么通過(guò)參數(shù)傳遞。造成大量的實(shí)例化對(duì)象闭翩,并且他們的生命周期可能就是從方法的調(diào)用開(kāi)始到方法的調(diào)用結(jié)束為止挣郭,加大了GC回收的壓力。了解設(shè)計(jì)模式的會(huì)想到使用單例模式的方式來(lái)解決問(wèn)題疗韵。

采用單例模式的問(wèn)題兑障,第一是大量的代碼需要改造、大量的重復(fù)單例模版代碼蕉汪;其次是單例模式需要把單例模版代碼和業(yè)務(wù)代碼放在一起流译。

解決方案類(lèi)似于連接池,我們把連接放在一個(gè)池子里者疤,需要建立連接則直接在池子中找空閑連接資源福澡。這個(gè)池子的思想就是spring容器的原型。

2. bean的生命周期與擴(kuò)展點(diǎn)

IoC 容器管理bean的生命周期驹马,在不同階段革砸,Spring 提供了不同的擴(kuò)展點(diǎn)來(lái)改變bean的命運(yùn)除秀。

1)容器啟動(dòng)階段,BeanFactoryPostProcessor可以在實(shí)例化對(duì)象前算利,對(duì)注冊(cè)到容器的BeanDefinition進(jìn)行操作册踩,如修改bean的屬性等。有自定義需求需要實(shí)現(xiàn)BeanFactoryPostProcessor接口笔时;另外棍好,如果容器中有多個(gè)BeanFactoryPostProcessor,需實(shí)現(xiàn)Ordered接口允耿,以保證BeanFactoryPostProcessor按序執(zhí)行借笙。

??:spring支持把配置屬性統(tǒng)一放在properties文件,bean中用${}引用较锡,從而方便配置屬性的統(tǒng)一管理业稼、及運(yùn)維人員維護(hù)不同環(huán)境的配置,該功能通過(guò)PropertyPlaceholderConfigurer實(shí)現(xiàn)蚂蕴,該類(lèi)實(shí)現(xiàn)BeanFactoryPostProcessor接口低散。容器啟動(dòng)階段完成后,BeanDefinition保存的對(duì)象屬性是占位符骡楼;執(zhí)行PropertyPlaceholderConfigurer將占位符替換為properties文件中的屬性值熔号。第二階段實(shí)例化bean時(shí),bean定義中的屬性值已完成替換鸟整。

2)對(duì)象實(shí)例化階段引镊,BeanPostProcessor處理容器內(nèi)所有符合條件且已經(jīng)實(shí)例化的對(duì)象。BeanFactoryPostProcessor處理beanDefinition篮条;BeanPostProcessor處理bean實(shí)例弟头。該接口提供兩個(gè)方法:postProcessBefore/AfterInitialization。注解涉茧、AOP等功能的實(shí)現(xiàn)大量使用BeanPostProcessor赴恨,比如我可以自定義一個(gè)注解,同時(shí)實(shí)現(xiàn)BeanPostProcessor接口伴栓,在實(shí)現(xiàn)類(lèi)中判斷bean實(shí)例是否有該注解伦连,如果有,則對(duì)bean實(shí)例執(zhí)行響應(yīng)操作钳垮。

Spring中有很多Aware接口惑淳,其作用就是在對(duì)象實(shí)例化完成后將Aware接口中規(guī)定的依賴(lài)注入到當(dāng)前實(shí)例中。比如最常見(jiàn)的ApplicationContextAware接口扔枫,實(shí)現(xiàn)了這個(gè)接口的類(lèi)都可以獲取到一個(gè)ApplicationContext對(duì)象汛聚。當(dāng)容器中每個(gè)對(duì)象的實(shí)例化過(guò)程走到BeanPostProcessor前置處理這一步時(shí),容器會(huì)檢測(cè)到之前注冊(cè)到容器的ApplicationContextAwareProcessor短荐,然后就會(huì)調(diào)用其postProcessBeforeInitialization()方法倚舀,檢查并設(shè)置Aware相關(guān)依賴(lài)叹哭。(Q)

Bean的生命周期

三、JavaConfig與注解

最初Spring使用XML配置bean的定義與依賴(lài)關(guān)系痕貌,缺點(diǎn)是大量的XML文件使項(xiàng)目變得復(fù)雜且難以管理风罩。后來(lái),基于純Java Annotation依賴(lài)注入框架?Guice出世舵稠,其性能明顯優(yōu)于采用XML方式的Spring超升,甚至有人認(rèn)為,?Guice可以取代Spring哺徊。正是這樣的危機(jī)感室琢,促使Spring推出JavaConfig項(xiàng)目,基于Java代碼和Annotation注解來(lái)描述bean之間的依賴(lài)綁定關(guān)系落追。

@ComponentScan表示Spring會(huì)自動(dòng)掃描所有通過(guò)注解配置的bean盈滴,并注冊(cè)到IOC容器中。basePackages屬性可指定掃描范圍轿钠,不指定則默認(rèn)從聲明?@ComponentScan所在類(lèi)的package進(jìn)行掃描巢钓。正因?yàn)槿绱耍琒pringBoot的啟動(dòng)類(lèi)都默認(rèn)在?src/main/java下疗垛。

@Conditional表示僅當(dāng)指定條件成立時(shí)才會(huì)創(chuàng)建對(duì)應(yīng)bean症汹,否則忽略bean的聲明。

四贷腕、自動(dòng)配置原理

Spring Boot根據(jù)依賴(lài)背镇、自定義的bean、classpath下有沒(méi)有某個(gè)類(lèi)等因素來(lái)猜測(cè)你需要的bean花履,然后注冊(cè)到IOC容器中芽世。猜測(cè)的動(dòng)作由EnableAutoConfigurationImportSelector進(jìn)行挚赊,這個(gè)bean通過(guò)@EnableAutoConfiguration注入到容器诡壁。

SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,this.beanClassLoader)));

上述代碼中,SpringFactoriesLoader搜索Jar包中的META-INF/spring.factories文件如下荠割,找到指定名稱(chēng)的@Configuration類(lèi)妹卿, 然后通過(guò)反射實(shí)例化這些類(lèi)并注入到IOC容器。

spring.factories

以?DataSourceAutoConfiguration為例:

DataSourceAutoConfiguration.java

@ConditionalOnClass({DataSource.class,EmbeddedDatabaseType.class})表示僅當(dāng)Classpath中存在DataSource或者EmbeddedDatabaseType類(lèi)時(shí)才啟用這個(gè)配置蔑鹦。@EnableConfigurationProperties(DataSourceProperties.class)將DataSource的默認(rèn)配置類(lèi)注入到IOC容器中.

DataSourceProperties.java

回顧一下夺克,@EnableAutoConfiguration中導(dǎo)入了EnableAutoConfigurationImportSelector類(lèi),而這個(gè)類(lèi)的selectImports()通過(guò)SpringFactoriesLoader得到了大量的配置類(lèi)嚎朽,而每一個(gè)配置類(lèi)則根據(jù)條件化配置來(lái)做出決策铺纽,以實(shí)現(xiàn)自動(dòng)配置。

五哟忍、啟動(dòng)引導(dǎo):spring boot應(yīng)用啟動(dòng)的秘密

1. SpringBoot整個(gè)啟動(dòng)流程的兩個(gè)步驟

1)初始化一個(gè)SpringApplication對(duì)象狡门;通過(guò)SpringFactoriesLoader找到?spring.factories文件中配置的?ApplicationContextInitializer和?ApplicationListener兩個(gè)接口的實(shí)現(xiàn)類(lèi)名稱(chēng)陷寝,以便后期構(gòu)造相應(yīng)的實(shí)例。?ApplicationContextInitializer的主要目的是在?ConfigurableApplicationContext做refresh之前其馏,對(duì)ConfigurableApplicationContext實(shí)例做進(jìn)一步的設(shè)置或處理凤跑。ConfigurableApplicationContext繼承自ApplicationContext,其主要提供了對(duì)ApplicationContext進(jìn)行設(shè)置的能力叛复。

2)執(zhí)行該對(duì)象的run方法

(1)通過(guò)SpringFactoriesLoader查找并加載所有的?SpringApplicationRunListeners仔引;SpringApplicationRunListeners本質(zhì)上是事件發(fā)布者,它在SpringBoot應(yīng)用啟動(dòng)的不同時(shí)間點(diǎn)發(fā)布不同應(yīng)用事件類(lèi)型(ApplicationEvent)褐奥,如果有哪些事件監(jiān)聽(tīng)者(ApplicationListener)對(duì)這些事件感興趣咖耘,則可以接收并且處理。

(2)創(chuàng)建并配置當(dāng)前應(yīng)用將要使用的Environment撬码,如果是web項(xiàng)目就創(chuàng)建?StandardServletEnvironment鲤看,描述應(yīng)用程序當(dāng)前的運(yùn)行環(huán)境,包括profile耍群、properties义桂,不同的環(huán)境(eg:生產(chǎn)環(huán)境、預(yù)發(fā)布環(huán)境)使用不同的配置文件蹈垢,屬性則從配置文件慷吊、環(huán)境變量、命令行參數(shù)獲取曹抬。Environment準(zhǔn)備好后溉瓶,調(diào)用SpringApplicationRunListener的?environmentPrepared()方法,通知事件監(jiān)聽(tīng)者:在整個(gè)應(yīng)用的任何時(shí)候谤民,都可以從Environment中獲取資源堰酿。

(3)打印spring banner

(4)初始化ApplicationContext,將準(zhǔn)備好的Environment設(shè)置給ApplicationContext张足;遍歷所有ApplicationContextInitializer對(duì)已經(jīng)創(chuàng)建好的ApplicationContext進(jìn)一步處理触创;調(diào)用SpringApplicationRunListener的contextPrepared()方法,通知所有的監(jiān)聽(tīng)者ApplicationContext已經(jīng)準(zhǔn)備完畢为牍;將所有的bean加載到容器中哼绑;調(diào)用SpringApplicationRunListener的?contextLoaded()方法,通知所有的監(jiān)聽(tīng)者ApplicationContext已經(jīng)裝載完畢碉咆。

(5)調(diào)用ApplicationContext的?refresh()方法抖韩,完成IoC容器可用的最后一道工序:獲取所有BeanFactoryPostProcessor在容器實(shí)例化對(duì)象前,對(duì)BeanDefinition進(jìn)行額外操作疫铜。

這就是Spring Boot的整個(gè)啟動(dòng)流程茂浮,其核心就是在Spring容器初始化并啟動(dòng)的基礎(chǔ)上加入各種擴(kuò)展點(diǎn),這些擴(kuò)展點(diǎn)包括:ApplicationContextInitializer、ApplicationListener以及各種BeanFactoryPostProcessor等等席揽。

2. Spring的事件監(jiān)聽(tīng)機(jī)制

過(guò)去佃乘,事件監(jiān)聽(tīng)機(jī)制多用于圖形界面編程,比如點(diǎn)擊按鈕等操作被稱(chēng)為事件驹尼,而當(dāng)事件觸發(fā)時(shí)趣避,應(yīng)用程序作出一定的響應(yīng)則表示應(yīng)用監(jiān)聽(tīng)了這個(gè)事件。服務(wù)器端新翎,事件的監(jiān)聽(tīng)機(jī)制更多的用于異步通知以及監(jiān)控和異常處理程帕。Java提供了實(shí)現(xiàn)事件監(jiān)聽(tīng)機(jī)制的兩個(gè)基礎(chǔ)類(lèi):自定義事件類(lèi)型EventObject、事件的監(jiān)聽(tīng)器EventListener地啰。EventListener有兩個(gè)方法:onMethodBegin/End愁拭。事件監(jiān)聽(tīng)中涉及事件發(fā)布者、事件亏吝、事件監(jiān)聽(tīng)者岭埠。

Spring的ApplicationContext容器內(nèi)部中的所有事件類(lèi)型均繼承自 AppliationEvent(EventObject子類(lèi)),所有監(jiān)聽(tīng)器都實(shí)現(xiàn)ApplicationListener接口(EventListener)蔚鸥。一旦在容器內(nèi)發(fā)布ApplicationEvent惜论,注冊(cè)到容器的ApplicationListener就會(huì)對(duì)這些事件進(jìn)行處理。Spring提供默認(rèn)實(shí)現(xiàn)如:?ContextClosedEvent表示容器在即將關(guān)閉時(shí)發(fā)布的事件止喷,?ContextRefreshedEvent表示容器在初始化或者刷新的時(shí)候發(fā)布的事件馆类。

六、DispatchServlet

DispatcherServlet的init方法里面load了springmvc的配置信息弹谁,然后初始化了spring容器(調(diào)用了refresh方法)岔冀,把controller的信息緩存了候学,比如映射信息;然后DispatcherServlet會(huì)攔截所有的請(qǐng)求沾谓,根據(jù)用戶(hù)的請(qǐng)求信息通過(guò)緩存的映射信息找到對(duì)應(yīng)的controller的對(duì)應(yīng)方法计螺,然后反射調(diào)用(其實(shí)底層的源碼就是反射調(diào)用controller的方法)啰脚,然后視圖裁決效扫、解析等等工作看幼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市向图,隨后出現(xiàn)的幾起案子泳秀,更是在濱河造成了極大的恐慌标沪,老刑警劉巖榄攀,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異金句,居然都是意外死亡檩赢,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贞瞒,“玉大人偶房,你說(shuō)我怎么就攤上這事【” “怎么了棕洋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)乒融。 經(jīng)常有香客問(wèn)我掰盘,道長(zhǎng),這世上最難降的妖魔是什么赞季? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任愧捕,我火速辦了婚禮,結(jié)果婚禮上申钩,老公的妹妹穿的比我還像新娘次绘。我一直安慰自己,他們只是感情好撒遣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布邮偎。 她就那樣靜靜地躺著,像睡著了一般义黎。 火紅的嫁衣襯著肌膚如雪钢猛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天轩缤,我揣著相機(jī)與錄音命迈,去河邊找鬼。 笑死火的,一個(gè)胖子當(dāng)著我的面吹牛壶愤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播馏鹤,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼征椒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了湃累?” 一聲冷哼從身側(cè)響起勃救,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎治力,沒(méi)想到半個(gè)月后蒙秒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宵统,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年晕讲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓢省,死狀恐怖弄息,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勤婚,我是刑警寧澤摹量,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站馒胆,受9級(jí)特大地震影響荆永,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜国章,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一具钥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧液兽,春花似錦骂删、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至柑晒,卻和暖如春欧瘪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匙赞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工佛掖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涌庭。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓芥被,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親坐榆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拴魄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 2.1 我們的理念是:讓別人為你服務(wù) IoC是隨著近年來(lái)輕量級(jí)容器(Lightweight Container)的...
    好好學(xué)習(xí)Sun閱讀 2,713評(píng)論 0 11
  • 如果有看過(guò)SpringApplication.run()方法的源碼,Spring Boot冗長(zhǎng)無(wú)比的啟動(dòng)流程一定會(huì)...
    codingKeeper閱讀 300評(píng)論 0 0
  • 概述 關(guān)于Spring Spring作為目前Java領(lǐng)域最熱門(mén)的開(kāi)發(fā)框架席镀,是一個(gè)Java程序員最常用的框架匹中,并且在...
    emi1997閱讀 2,124評(píng)論 1 20
  • 1- IOC的概念 IOC:也即控制反轉(zhuǎn),DI即依賴(lài)注入豪诲,控制反轉(zhuǎn)IOC和依賴(lài)注入DI其實(shí)就是同個(gè)概念的兩個(gè)不同...
    zhanglbjames閱讀 3,019評(píng)論 1 3
  • 月亮在我的頭上 你在我的心上
    滌高閱讀 66評(píng)論 0 3