首先想說說IoC(Inversion of Control,控制反轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。這是什麼意思呢,舉個簡單的例子,咱們是如何找女友的?常見的狀況是,咱們處處去看哪裏有長得漂亮身材又好的mm,而後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,而後嘿嘿……這個過程是複雜深奧的,咱們必須本身設計和麪對每一個環節。傳統的程序開發也是如此,在一個對象中,若是要使用另外的對象,就必須獲得它(本身new一個,或者從JNDI中查詢一個),使用完以後還要將對象銷燬(好比Connection等),對象始終會和其餘的接口或類藕合起來。java
那麼IoC是如何作的呢?有點像經過婚介找女友,在我和女友之間引入了一個第三者:婚姻介紹所。婚介管理了不少男男女女的資料,我能夠向婚介提出一個列表,告訴它我想找個什麼樣的女友,好比長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,而後婚介就會按照咱們的要求,提供一個mm,咱們只須要去和她談戀愛、結婚就好了。簡單明瞭,若是婚介給咱們的人選不符合要求,咱們就會拋出異常。整個過程再也不由我本身控制,而是有婚介這樣一個相似容器的機構來控制。Spring所倡導的開發方式就是如此,全部的類都會在spring容器中登記,告訴spring你是個什麼東西,你須要什麼東西,而後spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其餘須要你的東西。全部的類的建立、銷燬都由 spring來控制,也就是說控制對象生存週期的再也不是引用它的對象,而是spring。對於某個具體的對象而言,之前是它控制其餘對象,如今是全部對象都被spring控制,因此這叫控制反轉。web
IoC的一個重點是在系統運行中,動態的向某個對象提供它所須要的其餘對象。這一點是經過DI(Dependency Injection,依賴注入)來實現的。好比對象A須要操做數據庫,之前咱們老是要在A中本身編寫代碼來得到一個Connection對象,有了 spring咱們就只須要告訴spring,A中須要一個Connection,至於這個Connection怎麼構造,什麼時候構造,A不須要知道。在系統運行時,spring會在適當的時候製造一個Connection,而後像打針同樣,注射到A當中,這樣就完成了對各個對象之間關係的控制。A須要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? Java 1.3以後一個重要特徵是反射(reflection),它容許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是經過反射來實現注入的。spring
理解了IoC和DI的概念後,一切都將變得簡單明瞭,剩下的工做只是在spring的框架中堆積木而已。數據庫
用圖例說明一下,傳統程序設計如圖1-1,都是主動去建立相關對象而後再組合起來:瀏覽器
圖1-1 傳統應用程序示意圖app
當有了IoC/DI的容器後,在客戶端類中再也不主動去建立這些對象了,如圖1-2所示:框架
圖1-2有IoC/DI容器後程序結構示意圖測試
拍電影你們都知道,須要編劇,導演,演員,攝影師。就拿《大話西遊》這部電影來舉例把。this
編劇(寫代碼的程序猿):編劇在編寫劇本的時候,是不知道劇本中的至尊寶和紫霞仙子的演員是誰的。也就是說編劇只關注個人劇本中的角色以及劇情,不關心這些角色由誰來扮演。spa
導演(spring容器):導演須要負責演員的挑選以及其餘工做。
演員(被管理的對象): 演員有不少,劉德華啊,張學友啊,周星馳什麼的。
攝影師(模擬程序運行):按照劇本和選擇的演員,拍攝電影。
spring的控制反轉:導演,就充當着spring容器的做用,前來應聘的演員都在導演這裏登記,由導演來管理(如spring管理對象的生命週期,對象的建立和銷燬)。假如如今劉德華,張學友,周星馳都想應聘《大話西遊》,導演會錄入他們的我的信息並登記。也就是說,電影中角色扮演者是由導演一手控制。編劇和攝像師不須要考慮誰來演這個問題,只須要管好本身的事情。(解耦)
spring的依賴注入: 編劇方面,在演員沒有肯定好以前,劇本中的人物都是虛幻的,沒有實例化的,也就是還沒法開拍(程序沒法運行,由於有些依賴沒有到位),但這並不影響編劇寫劇本。spring的依賴注入,在電影這個例子中能夠解釋爲-在導演肯定好演員,編劇寫好劇本後,就該正式開拍了。拍攝是按照劇原本的,劇本中的人物又須要現實的明星來表演,這裏就要用到依賴注入了。好比劇本中至尊寶帶金剛圈的劇情,拍攝時須要人來演至尊寶,就找導演要人(找spring要合適的對象),導演已經肯定了周星馳比較適合演至尊寶,就直接把周星馳扔給他們。
目錄結構:
Person類,表示人(演員都是人)。有get,set方法。
person類有一個say(String str)的方法,就是人說話。(模擬演員說臺詞)
package com.sicau.test; /** * Person * create by chenshihang on 2018/10/26 */ public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void say(String str){ System.out.println(this.getName()+"口音:"+str); } }
TestController類。用來測試
這個類能夠看做是編劇,寫劇本。能夠看到,這段劇本須要兩個Person,一個角色是自尊包,一個角色是紫霞。(但編劇並不關心具體演員是誰)
package com.sicau.controller; import com.sicau.test.A; import com.sicau.test.Person; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; /** * TestController * create by chenshihang on 2018/10/24 */ @Controller public class TestController { @Autowired//默認是經過type匹配 @Qualifier("zhizunbao")//結合該註解,能夠經過name去匹配 private Person zhizunbao; @Autowired @Qualifier("zixia") private Person zixia; @RequestMapping("/toTest1.form") public String Test1(){ System.out.println("toTest1"); zhizunbao.say("hehe"); zixia.say("haha"); return "test"; } }
spring容器核心配置文件 applicationContext.xml
導演肯定了至尊寶的表演者是周星馳,紫霞的表演者是朱茵
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.sicau.*"/> <bean id="zhizunbao" class="com.sicau.test.Person"> <property name="age" value="1"/> <property name="name" value="z周星馳"/> </bean> <bean id="zixia" class="com.sicau.test.Person"> <property name="age" value="12"/> <property name="name" value="朱茵"/> </bean> </beans>
當程序運行時(拍攝時)
瀏覽器訪問:
進入編劇寫好的劇本Test1
導演將周星馳和朱茵扔給攝影師,周星馳和朱茵就充當了至尊寶和紫霞
正式表演,劇本中至尊寶說hehe,紫霞說haha(程序運行)
控制檯打印出信息: