Spring學(xué)習(xí)() Bean配置的三種方式(XML、注解毫目、Java類)介紹與對(duì)比

本文將詳細(xì)介紹Spring Bean配置的三種不同方式的特點(diǎn)與使用條件。

主要包括:

基于XML的配置方式

基于注解的配置方式

基于Java類的配置方式



一.基于XML的配置

我們應(yīng)該怎么理解和認(rèn)識(shí)Spring的配置文件呢诲侮?

? ? ? ? 其實(shí)镀虐,Spring的配置文件是Spring容器對(duì)Bean進(jìn)行生產(chǎn)以及關(guān)系注入的圖紙,他是Spring的基礎(chǔ)沟绪。如果我們沒有配置文件的話刮便,則Spring的容器將無從談起。

? ? ? ? Spring 的配置文件是用于指導(dǎo) Spring 工廠進(jìn)行 Bean 的生產(chǎn)绽慈、依賴關(guān)系注入及 Bean 實(shí)例分發(fā)的“圖紙”恨旱, J2EE 程序員必須學(xué)會(huì)并靈活應(yīng)用這份“圖紙”,準(zhǔn)確地表達(dá)自己的“生產(chǎn)意圖”坝疼。它是一個(gè)或多個(gè)標(biāo)準(zhǔn)的XML文檔搜贤,其ApplicationContext.xml是Spring的默認(rèn)配置文件,當(dāng)容器啟動(dòng)時(shí)找不到其他的配置文件時(shí)钝凶,則會(huì)嘗試加載這個(gè)默認(rèn)的配置文件仪芒。

Spring容器成功啟動(dòng)需要以下三方面的條件同時(shí)具備:

Spring的類包必須已經(jīng)放在Spring的類容器下面

應(yīng)用程序應(yīng)當(dāng)為Spring提供完備的Bean的配置信息

Bean的類都已經(jīng)放在Spring的類容器下面? ??

Spring啟動(dòng)時(shí)讀取應(yīng)用程序提供的Bean的配置信息,并在Spring容器中生成一份相應(yīng)的Bean的配置注冊(cè)表耕陷,然后根據(jù)這張注冊(cè)表來實(shí)例化Bean掂名,裝配好Bean之間的依賴關(guān)系,為上層應(yīng)用提供準(zhǔn)備就緒的運(yùn)行環(huán)境哟沫。

而bean的配置信息就是Bean的元數(shù)據(jù)信息饺蔑,他由以下五個(gè)方面來組成:

Bean的實(shí)現(xiàn)類

Bean的屬性信息 比如:數(shù)據(jù)源的連接數(shù),用戶名和密碼等等嗜诀。

Bean的依賴關(guān)系 Spring根據(jù)依賴關(guān)系配置完成Bean之間的裝配

Bean的行為配置 比如:生命周期范圍以及生命周期各個(gè)過程的回調(diào)函數(shù)等

Bean的創(chuàng)建方式定義 主要說明是通過構(gòu)造器還是工廠方法來構(gòu)造Bean

接下來是他們之間的相互關(guān)系:


有時(shí)猾警,一個(gè)項(xiàng)目中可能存在多個(gè)配置文件,那么Spring項(xiàng)目加載多個(gè)配置文件的方法:

在配置文件中使用import來導(dǎo)入所需的配置文件裹虫。

將多個(gè)配置文件構(gòu)造為一個(gè)數(shù)組肿嘲,然后傳遞給ApplicationContext實(shí)現(xiàn)加載多個(gè)配置文件。

這兩種方式都是通過調(diào)用BeanDefinitionReader來讀取定義文件的筑公,在內(nèi)部實(shí)現(xiàn)上沒有任何的區(qū)別雳窟。

? ? ??在大型的Spring項(xiàng)目當(dāng)中,所有的bean配置在一個(gè)配置文件當(dāng)中很不容易管理且也不利于團(tuán)隊(duì)的開發(fā)。通常在開發(fā)過程當(dāng)中封救,我們會(huì)按照功能模塊和開發(fā)人員來將配置文件分成多個(gè)拇涤。這樣會(huì)有利與模塊的劃分。接下來我們需要使用import屬性來引入多個(gè)配置文件到項(xiàng)目當(dāng)中誉结。

假如我們的項(xiàng)目需要用到多個(gè)配置文件鹅士,且配置文件位于不同的文件夾下,比如:

Spring-Common.xml位于common文件夾下

Spring-Connection.xml位于connection文件夾下

Spring-Module.xml位于module文件夾下

傳統(tǒng)加載方式:


但是這種方法不宜組織惩坑,且不宜維護(hù)掉盅。

則我們使用整合配置文件:Spring-All-Module.xml


在文件當(dāng)中使用import直接將其他的配置文件導(dǎo)入到這個(gè)文件當(dāng)中就好了。

整合后加載方式:

ApplicationContext?context?=?new?ClassPathXmlApplicationContext(“Spring-All-Module.xml”);??


可以看到配置文件是整個(gè)Spring項(xiàng)目的靈魂以舒,我們先來看一下Spring配置文件的一般結(jié)構(gòu):


可以看到一個(gè)簡(jiǎn)單的Spring配置文件就是這樣趾痘。

其中:

Import標(biāo)簽可以放在Beans標(biāo)簽下的任何位置,沒有順序關(guān)系蔓钟。

bean3和bean2是同一個(gè)Bean永票,bean3是bean2的別名。

? ? ? ? Spring 的配置文件是基于XML格式的滥沫,Spring1.0的配置文件采用DTD格式侣集,Spring2.0以后使用Schema的格式,后者讓不同類型的配置擁有了自己的命名空間兰绣,使配置文件更具有擴(kuò)展性世分。

采取基于Schema的配置格式,文件頭的聲明會(huì)復(fù)雜一些狭魂,請(qǐng)看一個(gè)簡(jiǎn)單示例:


我們?cè)谏厦娴拇a中定義了三個(gè)命名空間罚攀,

首先我們定義了一個(gè)默認(rèn)命名空間,他沒有空間名雌澄,用于Spring Bean的定義。

接下來我們命名了一個(gè)xsi命名空間杯瞻,這個(gè)命名空間用于為每個(gè)文檔中命名空間指定相對(duì)應(yīng)的schema的樣式文件镐牺。是標(biāo)準(zhǔn)組織定義的標(biāo)準(zhǔn)命名空間。

我們還命名了一個(gè)aop的命名空間魁莉,這個(gè)命名空間是Spring配置aop的命名空間睬涧,是用戶自定義的命名空間。

命名空間的定義分為了兩個(gè)步驟:

指定命名空間的名稱旗唁,需要指定命名空間的縮類名和全名

指定命名空間的schema文檔樣式文件的位置畦浓,用空格或回車行來進(jìn)行分割。

指定命名空間schema地址有兩個(gè)用途:

xml解析器可以獲取schema文件检疫,并對(duì)文檔進(jìn)行格式合法性驗(yàn)證

在開發(fā)環(huán)境下讶请,IDE可以用schema文件來對(duì)文檔編輯器進(jìn)行誘導(dǎo)功能。

Spring3.0 的配置Schema文件分布在各模塊類包中屎媳,如果模塊擁有對(duì)應(yīng)的Schema文件夺溢,則可以在模塊類包中找到一個(gè)config目錄论巍,Schema文件就位于該目錄中,如下是對(duì)這些Schema文件的用途進(jìn)行了簡(jiǎn)單說明:

示例說明:Spring-beans-3.0.xsd

命名空間:http://www.springframework.org/schema/beans

Schema 文件:http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

可以看出在Spring3.0當(dāng)中风响,所有的Schema文件的命名空間以及對(duì)應(yīng)的位置都和Beans這個(gè)Schema文件是類似的嘉汰。

那么接下來來了解以下Spring當(dāng)中其他Schema文件的用途:

spring-beans-3.0.xsd:Spring3.0最主要的配置文件,主要是用于配置Bean

spring-aop-3.0.xsd:aop配置定義的schema

spring-tx-3.0.xsd:聲明式事物配置定義的Schema

spring-mvc-3.0.xsd:Spring3.0當(dāng)中新增的

spring-util-3.0.xsd:是為簡(jiǎn)化某些復(fù)雜的標(biāo)準(zhǔn)配置而提供的Schema

spring-jee-3.0.xsd:是為簡(jiǎn)化J2EE中EJB等功能的配置而提供的Schema

spring-jdbc-3.0.xsd:為Spring內(nèi)接數(shù)據(jù)庫(kù)而提供的Schema状勤,3.0新增

spring-jms-3.0.xsd:jms配置的Schema

spring-lang-3.0.xsd:增加了對(duì)動(dòng)態(tài)語(yǔ)言的支持鞋怀,為集成動(dòng)態(tài)語(yǔ)言而定義

spring-oxm-3.0.xsd:配置對(duì)象xml映射到schema,3.0新增

spring-task-3.0.xsd:任務(wù)調(diào)度的Schema

spring-tool-3.0.xsd:為集成Schema一些有用工具而提供的Schema


二.基于注解的配置

Spring2.0開始引入基于注解的配置方式,即Bean的定義信息可以通過在Bean的實(shí)現(xiàn)類上標(biāo)注注解實(shí)現(xiàn)持搜。

具體關(guān)于注解的知識(shí)請(qǐng)看Java注解(Annotation)介紹

@Component是Spring容器中的基本注解密似,表示容器中的一個(gè)組件(bean),可以作用在任何層次朵诫,下面的示例介紹該注解的使用方法辛友。

注解配置示例:



此外,還有一些其他的可以被用來注解bean的注解剪返,這些可以讓注解類本身的用途更加清晰废累,此外,特定的注解也具備特定的功能脱盲。

Spring在2.5后提供了一個(gè)context的命名空間邑滨,它提供了通過掃描類包來加載利用注解定義的Bean的方式。

在context中可以使用resource-pattern來過濾出特定的類钱反。


默認(rèn)情況下加載的是package下的*.class即掃描全部類掖看,在使用了resource-pattern之后,則只掃描package下的anno子包下的所有類面哥。

不過使用resource-pattern并不能提供給我們完善的功能哎壳,所有我們得使用過濾子元素的方法。



其中:

include-filter表示要包含的目標(biāo)類尚卫,

exclude-filter表示要排除在外的目標(biāo)類



Spring3.0提供了一系列的針對(duì)依賴注入的注解归榕,這使得Spring IoC在XML文件之外多了一種可行的選擇,主要包含如下注解類型:

Bean的定義注解

Bean的生命周期注解

Bean的依賴檢查注解

Bean的自動(dòng)裝配注解

1.Bean的定義注解

Spring自2.0開始吱涉,陸續(xù)引入了一些注解用于簡(jiǎn)化Spring的開發(fā)刹泄。

@Repository注解便屬于最先引入的一批,用于將數(shù)據(jù)訪問層(DAO層)的類標(biāo)識(shí)為Spring Bean怎爵。具體使用如下:

①首先使用@Repository將DAO類聲明為Bean


如此的話特石,我們便不在需要在XML當(dāng)中顯式使用bean來進(jìn)行bean的配置。Spring容器在初始化的時(shí)候便會(huì)自動(dòng)掃描base-package所指定的包以及子包下面的所有class文件鳖链。所有標(biāo)注為Repository的類將被自動(dòng)注冊(cè)為bean姆蘸。

為什么Repository只能標(biāo)注在DAO類上面呢?

? ? ? ?因?yàn)樵撟⒔獾淖饔貌恢皇菍㈩愖R(shí)別為bean,同時(shí)他還能將所標(biāo)注的類中所拋出的數(shù)據(jù)訪問異常封裝為Spring的數(shù)據(jù)訪問異常類型乞旦。Spring本身提供了一個(gè)豐富的贼穆,并且是與具體的訪問技術(shù)無關(guān)的數(shù)據(jù)訪問異常結(jié)構(gòu),用于封裝不同的持久層框架所拋出的異常兰粉,使得異常獨(dú)立與底層的框架故痊。

Spring2.5在@Repository的基礎(chǔ)上增加了功能類似的額外三個(gè)注解,總共有如下四種注解:

@Component:一個(gè)泛化的概念玖姑,表示一個(gè)組件(Bean)愕秫,可作用在任何層次

@Controller:用于對(duì)Controller實(shí)現(xiàn)類進(jìn)行標(biāo)注,目前該功能與Component相同

@Repository:用于對(duì)DAO實(shí)現(xiàn)類進(jìn)行標(biāo)注

@Service:用于對(duì)Service實(shí)現(xiàn)類進(jìn)行標(biāo)注焰络,目前該功能與Component相同

這三個(gè)注解除了作用于不同軟件層次的類戴甩,其使用方式與Repository是完全相同的。

2.Bean的生命周期注解在某些情況下闪彼,可能需要我們手工做一些額外的初始化或者銷毀操作甜孤,例如資源的獲取和是否操作,Spring1.x為此提供了兩種方式供用戶指定執(zhí)行生命周期回調(diào)的方法:實(shí)現(xiàn)Spring提供的兩個(gè)接口:initializingBean 和 DisposableBean畏腕,這種方法是要求bean類實(shí)現(xiàn)Spring的接口缴川,但增加了bean和Spring容器的耦合度,因此不推薦使用描馅。在XML文件中使用的init-method 和 destory-method 屬性把夸,指定初始化之后和回調(diào)之前的回調(diào)方法。這兩個(gè)屬性的取值是bean中相應(yīng)的初始化和銷毀方法的名稱铭污。方法名稱任意恋日,但是方法不能有參數(shù)。

示例如下:


在這里嘹狞,我們指定了userService 這個(gè)bean的初始化方法為:init ? ? 銷毀方法為:destory

Spring2.5在保留以上兩種方式的基礎(chǔ)上岂膳,提供了對(duì)JSR-250的支持。

JSR-250規(guī)范定義了兩個(gè)用于指定聲明周期方法的注解:

@PostConstruct:初始化之后的執(zhí)行的回調(diào)方法

@PreDestroy:銷毀之前的回調(diào)方法

注解示例說明:


3.Bean的依賴檢查注解

Spring2.0之前使用dependency-check在配置文件中設(shè)置屬性用于依賴檢查(只會(huì)檢查Setter方法是否被調(diào)用)磅网,缺點(diǎn)是粒度較粗闷营,該屬性的取值包括以下幾種:

none: 默認(rèn)不執(zhí)行依賴檢查

simple :對(duì)原始基本類型和集合類型進(jìn)行檢查

objects :對(duì)復(fù)雜類型進(jìn)行檢查

all :對(duì)所有類型進(jìn)行檢查

使用Spring2.0提供的@Required注解,提供了更細(xì)粒度的控制知市,@Required注解只能標(biāo)注在Setter方法之上,(標(biāo)注在其他方法之上會(huì)被忽略 )用于檢查其是否被調(diào)用速蕊,當(dāng)Setter方法未被調(diào)用的話會(huì)拋出異常嫂丙。

由于使用了注解,所以得激活Bean的后處理器规哲,所以得在XML配置文件當(dāng)中增加



三.基于Java類的配置

基于Java類定義Bean配置元數(shù)據(jù)跟啤,其實(shí)就是通過Java類定義Spring配置元數(shù)據(jù),且直接消除XML配置文件。

首先讓我們看一下基于Java類如何定義Bean配置元數(shù)據(jù)隅肥,具體步驟如下:

使用@Configuration注解需要作為配置的類竿奏,表示該類將定義Bean的元數(shù)據(jù)

使用@Bean注解相應(yīng)的方法,該方法名默認(rèn)就是Bean的名稱腥放,該方法返回值就是Bean的對(duì)象泛啸。

AnnotationConfigApplicationContext或子類進(jìn)行加載基于java類的配置

接下來通過示例來演示下如何基于Java類來配置Spring

首先創(chuàng)建一個(gè)配置類


然后還需要一個(gè)測(cè)試類,來查看配置是否成功



基于Java方式的配置方式不是為了完全替代基于XML方式的配置秃症,兩者可以結(jié)合使用候址,因此可以有兩種結(jié)合使用方式:

在基于Java方式的配置類中引入基于XML方式的配置文件

在基于XML方式的配置文件中中引入基于Java方式的配置




總結(jié):不同配置方式比較

我們來看一下不同配置方式在不同方面的使用



其實(shí)Spring支持這么多的配置方式,那么這些配置方式必然有其自己獨(dú)特的舞臺(tái)

基于XML的配置主要使用場(chǎng)景:

第三方類庫(kù)种柑,如DataSource岗仑、JdbcTemplate等;

命名空間聚请,如aop荠雕、context等;

基于注解的配置主要使用場(chǎng)景:

Bean的實(shí)現(xiàn)類是當(dāng)前項(xiàng)目開發(fā)的驶赏,可直接在Java類中使用注解配置

基于Java類的配置主要使用場(chǎng)景:

對(duì)于實(shí)例化Bean的邏輯比較復(fù)雜炸卑,則比較適合用基于Java類配置的方式

在日常的開發(fā)中我們主要是使用XML配置和注解配置方式向結(jié)合的開發(fā)方式,一般不推薦使用基于Java類的配置方式母市。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末矾兜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子患久,更是在濱河造成了極大的恐慌椅寺,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒋失,死亡現(xiàn)場(chǎng)離奇詭異返帕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)篙挽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門荆萤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人铣卡,你說我怎么就攤上這事链韭。” “怎么了煮落?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵胸梆,是天一觀的道長(zhǎng)怀吻。 經(jīng)常有香客問我筝家,道長(zhǎng)瑰钮,這世上最難降的妖魔是什么殖蚕? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮沉迹,結(jié)果婚禮上睦疫,老公的妹妹穿的比我還像新娘。我一直安慰自己鞭呕,他們只是感情好蛤育,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著琅拌,像睡著了一般缨伊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上进宝,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天刻坊,我揣著相機(jī)與錄音,去河邊找鬼党晋。 笑死谭胚,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的未玻。 我是一名探鬼主播灾而,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼扳剿!你這毒婦竟也來了旁趟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤庇绽,失蹤者是張志新(化名)和其女友劉穎锡搜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞧掺,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耕餐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辟狈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肠缔。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖哼转,靈堂內(nèi)的尸體忽然破棺而出明未,到底是詐尸還是另有隱情,我是刑警寧澤壹蔓,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布亚隅,位于F島的核電站,受9級(jí)特大地震影響庶溶,放射性物質(zhì)發(fā)生泄漏煮纵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一偏螺、第九天 我趴在偏房一處隱蔽的房頂上張望行疏。 院中可真熱鬧,春花似錦套像、人聲如沸酿联。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贞让。三九已至,卻和暖如春柳譬,著一層夾襖步出監(jiān)牢的瞬間喳张,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工美澳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留销部,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓制跟,卻偏偏與公主長(zhǎng)得像舅桩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雨膨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

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