IoC(二)容器基本原理

2.2.1 IoC容器的概念

IoC容器就是具有依賴注入功能的容器,IoC容器負(fù)責(zé)實(shí)例化鲜漩、定位浇坐、配置應(yīng)用程序中的對(duì)象及建立這些對(duì)象間的依賴冰肴。應(yīng)用程序無(wú)需直接在代碼中new相關(guān)的對(duì)象勺拣,應(yīng)用程序由IoC容器進(jìn)行組裝奶赠。在Spring中BeanFactory是IoC容器的實(shí)際代表者。

Spring IoC容器如何知道哪些是它管理的對(duì)象呢药有?這就需要配置文件毅戈,Spring IoC容器通過(guò)讀取配置文件中的配置元數(shù)據(jù),通過(guò)元數(shù)據(jù)對(duì)應(yīng)用中的各個(gè)對(duì)象進(jìn)行實(shí)例化及裝配愤惰。一般使用基于xml配置文件進(jìn)行配置元數(shù)據(jù)苇经,而且Spring與配置文件完全解耦的,可以使用其他任何可能的方式進(jìn)行配置元數(shù)據(jù)宦言,比如注解扇单、基于java文件的、基于屬性文件的配置都可以奠旺。

那Spring IoC容器管理的對(duì)象叫什么呢蜘澜?

2.2.2 Bean的概念

由IoC容器管理的那些組成你應(yīng)用程序的對(duì)象我們就叫它Bean, Bean就是由Spring容器初始化凉倚、裝配及管理的對(duì)象兼都,除此之外,bean就與應(yīng)用程序中的其他對(duì)象沒(méi)有什么區(qū)別了稽寒。那IoC怎樣確定如何實(shí)例化Bean扮碧、管理Bean之間的依賴關(guān)系以及管理Bean呢?這就需要配置元數(shù)據(jù)杏糙,在Spring中由BeanDefinition代表慎王,后邊會(huì)詳細(xì)介紹,配置元數(shù)據(jù)指定如何實(shí)例化Bean宏侍、如何組裝Bean等赖淤。概念知道的差不多了,讓我們來(lái)做個(gè)簡(jiǎn)單的例子谅河。

2.2.3 Hello World

一咱旱、配置環(huán)境:

JDK安裝:安裝最新的JDK,至少需要Java 1.5及以上環(huán)境;

開(kāi)發(fā)工具:SpringSource Tool Suite,簡(jiǎn)稱STS霹肝,是個(gè)基于Eclipse的開(kāi)發(fā)環(huán)境辣垒,用以構(gòu)建Spring應(yīng)用柑贞,其最新版開(kāi)始支持Spring 3.0及OSGi開(kāi)發(fā)工具,但由于其太龐大,很多功能不是我們所必需的所以我們選擇Eclipse+ SpringSource Tool插件進(jìn)行Spring應(yīng)用開(kāi)發(fā)些阅;到eclipse官網(wǎng)下載最新的Eclipse狐粱,注意我們使用的是Eclipse IDE for Java EE Developers(eclipse-jee-helios-SR1)舀寓;

安裝插件:?jiǎn)?dòng)Eclipse,選擇Help->Install New Software肌蜻,如圖2-3所示

image.png

image.png

圖2-3 安裝

2互墓、首先安裝SpringSource Tool Suite插件依賴,如圖2-4:

Name為:SpringSource Tool Suite Dependencies

Location為:http://dist.springsource.com/release/TOOLS/composite/e3.6

image.png

圖2-4 安裝

3宋欺、安裝SpringSource Tool Suite插件轰豆,只需安裝如圖2-5所選中的就可以:

Name為:SpringSource Tool Suite

Location為:http://dist.springsource.com/release/TOOLS/update/e3.6

image.png

圖2-4 安裝

4胰伍、安裝完畢齿诞,開(kāi)始項(xiàng)目搭建吧。

Spring 依賴:本書使用spring-framework-3.0.5.RELEASE

                spring-framework-3.0.5.RELEASE-with-docs.zip表示此壓縮包帶有文檔的骂租;

                spring-framework-3.0.5.RELEASE-dependencies.zip表示此壓縮包中是spring的依賴jar包祷杈,所以需要什么依賴從這里找就好了;

               下載地址:http://www.springsource.org/download

二渗饮、開(kāi)始Spring Hello World之旅

1但汞、準(zhǔn)備需要的jar包

核心jar****包:從下載的spring-framework-3.0.5.RELEASE-with-docs.zip中dist目錄查找如下jar包

org.springframework.asm-3.0.5.RELEASE.jar

org.springframework.core-3.0.5.RELEASE.jar

org.springframework.beans-3.0.5.RELEASE.jar

org.springframework.context-3.0.5.RELEASE.jar

org.springframework.expression-3.0.5.RELEASE.jar

依賴的jar****包:從下載的spring-framework-3.0.5.RELEASE-dependencies.zip中查找如下依賴jar包
com.springsource.org.apache.log4j-1.2.15.jar

com.springsource.org.apache.commons.logging-1.1.1.jar

com.springsource.org.apache.commons.collections-3.2.1.jar

2、創(chuàng)建標(biāo)準(zhǔn)Java工程:

(1)選擇“window”—> “Show View” —>“Package Explorer”互站,使用包結(jié)構(gòu)視圖私蕾;

image.png

圖2-5 包結(jié)構(gòu)視圖

(2)創(chuàng)建標(biāo)準(zhǔn)Java項(xiàng)目,選擇“File”—>“New”—>“Other”胡桃;然后在彈出來(lái)的對(duì)話框中選擇“Java Project”創(chuàng)建標(biāo)準(zhǔn)Java項(xiàng)目踩叭;

image.png

圖2-6 創(chuàng)建Java項(xiàng)目

image.png

圖2-7 創(chuàng)建Java項(xiàng)目

image.png

圖2-8 創(chuàng)建Java項(xiàng)目

   (3)配置項(xiàng)目依賴庫(kù)文件,右擊項(xiàng)目選擇“Properties”翠胰;然后在彈出的對(duì)話框中點(diǎn)擊“Add JARS”在彈出的對(duì)話框中選擇“l(fā)ib”目錄下的jar包容贝;然后再點(diǎn)擊“Add Library”,然后在彈出的對(duì)話框中選擇“Junit”之景,選擇“Junit4”斤富;
image.png

圖2-9 配置項(xiàng)目依賴庫(kù)文件

image.png

圖2-10 配置項(xiàng)目依賴庫(kù)文件

image.png
image.png

圖2-11 配置項(xiàng)目依賴庫(kù)文件

(4)項(xiàng)目目錄結(jié)構(gòu)如下圖所示,其中“src”用于存放java文件锻狗;“l(fā)ib”用于存放jar文件满力;“resources”用于存放配置文件;

image.png

圖2-12 項(xiàng)目目錄結(jié)構(gòu)

3轻纪、項(xiàng)目搭建好了油额,讓我們來(lái)開(kāi)發(fā)接口,此處我們只需實(shí)現(xiàn)打印“Hello World!”桐磁,所以我們定義一個(gè)“sayHello”接口悔耘,代碼如下:

java代碼:

1.  package cn.javass.spring.chapter2.helloworld;  
2.  public interface HelloApi {  
3.  public void sayHello();  
4.  }  

4、接口開(kāi)發(fā)好了我擂,讓我們來(lái)通過(guò)實(shí)現(xiàn)接口來(lái)完成打印“Hello World!”功能衬以;

java代碼:

1.  package cn.javass.spring.chapter2.helloworld;  
2.  public class HelloImpl implements HelloApi {  
3.  @Override  
4.  public void sayHello() {  
5.  System.out.println("Hello World!");  
6.  }  
7.  }  

5缓艳、接口和實(shí)現(xiàn)都開(kāi)發(fā)好了,那如何使用Spring IoC容器來(lái)管理它們呢看峻?這就需要配置文件阶淘,讓IoC容器知道要管理哪些對(duì)象。讓我們來(lái)看下配置文件chapter2/helloworld.xml(放到resources目錄下):

java代碼:

1.  <?xml version="1.0" encoding="UTF-8"?>  
2.  <beans  
3.  xmlns="http://www.springframework.org/schema/beans"  
4.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
5.  xmlns:context="http://www.springframework.org/schema/context"  
6.  xsi:schemaLocation="  
7.  http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
8.  http://www.springframework.org/schema/context                http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
9.  <!-- id 表示你這個(gè)組件的名字互妓,class表示組件類 -->  
10.  <bean id="hello" class="cn.javass.spring.chapter2.helloworld.HelloImpl"></bean>  
11.  </beans>  

6溪窒、現(xiàn)在萬(wàn)一具備,那如何獲取IoC容器并完成我們需要的功能呢冯勉?首先應(yīng)該實(shí)例化一個(gè)IoC容器澈蚌,然后從容器中獲取需要的對(duì)象,然后調(diào)用接口完成我們需要的功能灼狰,代碼示例如下:

java代碼:

1.  package cn.javass.spring.chapter2.helloworld;  
2.  import org.junit.Test;  
3.  import org.springframework.context.ApplicationContext;  
4.  import org.springframework.context.support.ClassPathXmlApplicationContext;  
5.  public class HelloTest {  
6.  @Test  
7.  public void testHelloWorld() {  
8.  //1宛瞄、讀取配置文件實(shí)例化一個(gè)IoC容器  
9.  ApplicationContext context = new ClassPathXmlApplicationContext("helloworld.xml");  
10.  //2、從容器中獲取Bean交胚,注意此處完全“面向接口編程份汗,而不是面向?qū)崿F(xiàn)”  
11.  HelloApi helloApi = context.getBean("hello", HelloApi.class);  
12.  //3、執(zhí)行業(yè)務(wù)邏輯  
13.  helloApi.sayHello();  
14.  }  
15.  }  

7蝴簇、自此一個(gè)完整的Spring Hello World已完成杯活,是不是很簡(jiǎn)單,讓我們深入理解下容器和Bean吧熬词。

2.2.4 詳解IoC容器

在Spring Ioc容器的代表就是org.springframework.beans包中的BeanFactory接口旁钧,BeanFactory接口提供了IoC容器最基本功能;而org.springframework.context包下的ApplicationContext接口擴(kuò)展了BeanFactory荡澎,還提供了與Spring AOP集成均践、國(guó)際化處理、事件傳播及提供不同層次的context實(shí)現(xiàn) (如針對(duì)web應(yīng)用的WebApplicationContext)摩幔。簡(jiǎn)單說(shuō)彤委, BeanFactory提供了IoC容器最基本功能,而 ApplicationContext 則增加了更多支持企業(yè)級(jí)功能支持或衡。ApplicationContext完全繼承BeanFactory焦影,因而B(niǎo)eanFactory所具有的語(yǔ)義也適用于ApplicationContext。

容器實(shí)現(xiàn)一覽:

? XmlBeanFactory****:BeanFactory實(shí)現(xiàn)封断,提供基本的IoC容器功能斯辰,可以從classpath或文件系統(tǒng)等獲取資源;

(1) File file = new File("fileSystemConfig.xml");

       Resource resource = new FileSystemResource(file);

       BeanFactory beanFactory = new XmlBeanFactory(resource);

(2)

      Resource resource = new ClassPathResource("classpath.xml");                 

      BeanFactory beanFactory = new XmlBeanFactory(resource);

? ClassPathXmlApplicationContext****:ApplicationContext實(shí)現(xiàn)坡疼,從classpath獲取配置文件彬呻;

     BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath.xml");

? FileSystemXmlApplicationContext****:ApplicationContext實(shí)現(xiàn),從文件系統(tǒng)獲取配置文件。

     BeanFactory beanFactory = new FileSystemXmlApplicationContext("fileSystemConfig.xml");

具體代碼請(qǐng)參考cn.javass.spring.chapter2.InstantiatingContainerTest.java闸氮。

ApplicationContext接口獲取Bean方法簡(jiǎn)介:

? Object getBean(String name) 根據(jù)名稱返回一個(gè)Bean剪况,客戶端需要自己進(jìn)行類型轉(zhuǎn)換;

? T getBean(String name, Class<T> requiredType) 根據(jù)名稱和指定的類型返回一個(gè)Bean蒲跨,客戶端無(wú)需自己進(jìn)行類型轉(zhuǎn)換译断,如果類型轉(zhuǎn)換失敗,容器拋出異常或悲;

? T getBean(Class<T> requiredType) 根據(jù)指定的類型返回一個(gè)Bean孙咪,客戶端無(wú)需自己進(jìn)行類型轉(zhuǎn)換,如果沒(méi)有或有多于一個(gè)Bean存在容器將拋出異常巡语;

? Map<String, T> getBeansOfType(Class<T> type) 根據(jù)指定的類型返回一個(gè)鍵值為名字和值為Bean對(duì)象的 Map翎蹈,如果沒(méi)有Bean對(duì)象存在則返回空的Map。

讓我們來(lái)看下IoC容器到底是如何工作捌臊。在此我們以xml配置方式來(lái)分析一下:

一杨蛋、準(zhǔn)備配置文件:就像前邊Hello World配置文件一樣,在配置文件中聲明Bean定義也就是為Bean配置元數(shù)據(jù)理澎。

二、由IoC容器進(jìn)行解析元數(shù)據(jù): IoC容器的Bean Reader讀取并解析配置文件曙寡,根據(jù)定義生成BeanDefinition配置元數(shù)據(jù)對(duì)象糠爬,IoC容器根據(jù)BeanDefinition進(jìn)行實(shí)例化、配置及組裝Bean举庶。

三执隧、實(shí)例化IoC容器:由客戶端實(shí)例化容器,獲取需要的Bean户侥。

整個(gè)過(guò)程是不是很簡(jiǎn)單镀琉,執(zhí)行過(guò)程如圖2-5,其實(shí)IoC容器很容易使用蕊唐,主要是如何進(jìn)行Bean定義屋摔。下一章我們?cè)敿?xì)介紹定義Bean。


image.png

圖2-5 Spring Ioc容器

2.2.5 小結(jié)

除了測(cè)試程序的代碼外替梨,也就是程序入口钓试,所有代碼都沒(méi)有出現(xiàn)Spring任何組件,而且所有我們寫的代碼沒(méi)有實(shí)現(xiàn)框架擁有的接口副瀑,因而能非常容易的替換掉Spring弓熏,是不是非入侵。

客戶端代碼完全面向接口編程糠睡,無(wú)需知道實(shí)現(xiàn)類挽鞠,可以通過(guò)修改配置文件來(lái)更換接口實(shí)現(xiàn),客戶端代碼不需要任何修改。是不是低耦合信认。

如果在開(kāi)發(fā)初期沒(méi)有真正的實(shí)現(xiàn)串稀,我們可以模擬一個(gè)實(shí)現(xiàn)來(lái)測(cè)試,不耦合代碼狮杨,是不是很方便測(cè)試母截。

Bean之間幾乎沒(méi)有依賴關(guān)系,是不是很容易重用橄教。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末清寇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子护蝶,更是在濱河造成了極大的恐慌华烟,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件持灰,死亡現(xiàn)場(chǎng)離奇詭異盔夜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)堤魁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門喂链,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人妥泉,你說(shuō)我怎么就攤上這事椭微。” “怎么了盲链?”我有些...
    開(kāi)封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蝇率,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我刽沾,道長(zhǎng)本慕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任侧漓,我火速辦了婚禮锅尘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘火架。我一直安慰自己鉴象,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布何鸡。 她就那樣靜靜地躺著纺弊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骡男。 梳的紋絲不亂的頭發(fā)上淆游,一...
    開(kāi)封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼犹菱。 笑死拾稳,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腊脱。 我是一名探鬼主播访得,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陕凹!你這毒婦竟也來(lái)了悍抑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤杜耙,失蹤者是張志新(化名)和其女友劉穎搜骡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體佑女,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡记靡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了团驱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摸吠。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖店茶,靈堂內(nèi)的尸體忽然破棺而出蜕便,到底是詐尸還是另有隱情,我是刑警寧澤贩幻,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站两嘴,受9級(jí)特大地震影響丛楚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜憔辫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一趣些、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贰您,春花似錦坏平、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至杠园,卻和暖如春顾瞪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工陈醒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惕橙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓钉跷,卻偏偏與公主長(zhǎng)得像弥鹦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子爷辙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350