Spring學(xué)習(xí)筆記(四咧织、Bean裝配(上))

上一篇:Spring學(xué)習(xí)筆記(三秆吵、IoC)

** Bean常用的配置項**

  • Id:在IoC容器中Bean的唯一標(biāo)識
  • Class:具體要實例化的類
  • Scope:作用域
  • Constructor arguments:構(gòu)造器參數(shù)
  • properties:屬性
  • Autowiring mode:自動裝配模式
  • lazy-initialization mode:懶加載模式
  • initialization/destruction method:初始化/銷毀的方法

Bean的作用域

  • singleton:單例遏插,指一個Bean容器中只存在一份(默認(rèn))
  • prototype:每次請求(每次使用)創(chuàng)建新的實例,destory方法不生效(因為用完會被垃圾回收期回收)
  • request:每次http請求創(chuàng)建一個實例且僅在當(dāng)前request內(nèi)有效
  • session: 每次http請求創(chuàng)建一個實例且僅在當(dāng)前session內(nèi)有效
  • global session:基于portlet的web中有效(portlet定義了global session)渤弛,如果是在web中,同session

這里global session有可能還是不懂甚带,特此解釋:舉個例子她肯,一個大型的系統(tǒng),有多個獨立的模塊組成鹰贵,他們有一個統(tǒng)一的登錄入口晴氨,登錄進(jìn)入后,用戶可以在整個系統(tǒng)內(nèi)操作碉输,不需要在登錄其他模塊時籽前,重新登錄。這就是portlet的global session敷钾。

下面用例子證明:

  • singleton
    在TestDao增加接口:


    Paste_Image.png

    TestDaoImpl實現(xiàn):


    Paste_Image.png

    spring-ioc.xml:
    Paste_Image.png

    JUnit測試:
Paste_Image.png
Paste_Image.png

上圖可見枝哄,聲明了singleton作用域,即使獲取多次實例阻荒,也依舊是原來的那一個挠锥。

  • prototype

修改spring-ioc.xml:

Paste_Image.png

Junit測試結(jié)果變成:

Paste_Image.png

上圖可見,聲明了prototype作用域侨赡,獲取多次實例蓖租,每一次的hashcode都不同。

余下三個羊壹,由于涉及到web蓖宦,在此就不做測驗了。相信工作中舶掖,會有很多機會去嘗試球昨。

Bean的生命周期

  • 生命周期
    • 定義:在xml中定義<bean></bean>內(nèi)容
    • 初始化:IoC容器啟動(context.start();)時生成bean的實例
    • 使用:在測試或者開發(fā)時從Ioc容器中取出bean的實例調(diào)用它的方法
    • 銷毀:在IoC容器銷毀(context.destroy();)的時候尔店,銷毀它創(chuàng)建的所有實例眨攘。

生命周期 —— 初始化

  1. 實現(xiàn)org.springframework.beans.factory.InitializingBean接口主慰,重寫afterPropertiesSet方法
  2. 配置init-method
    以上兩種方法,可以在Ioc容器初始化實例時執(zhí)行一些實例內(nèi)部的初始化工作鲫售。
    下面分別舉例:

Paste_Image.png
Paste_Image.png

為了測試IoC容器啟動共螺,我加了一個空的測試方法。

Paste_Image.png

執(zhí)行后

Paste_Image.png

第一個【實現(xiàn)org.springframework.beans.factory.InitializingBean接口情竹,重寫afterPropertiesSet方法】測試初始化成功藐不。


Paste_Image.png
Paste_Image.png
Paste_Image.png

第二個【配置init-method】測試初始化成功。


**生命周期 —— 銷毀 **

  1. 實現(xiàn)org.springframework.beans.factory.DisposableBean接口秦效,重寫destroy方法
  2. 配置destroy-method
    這兩個銷毀方式和初始化測試方式是一樣的雏蛮,我就不做測試了。

還可以配置全局默認(rèn)初始化阱州、銷毀方法挑秉,就是為當(dāng)前IoC容器中所有的bean增加初始化和銷毀時執(zhí)行的方法

Paste_Image.png

既然實現(xiàn)初始化和銷毀有三種不同的方法,那么哪種優(yōu)先級最高呢苔货?下面來測試犀概。

package test4;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * Created by amber on 2017/5/27.
 */
public class TestInitial3 implements InitializingBean,DisposableBean {

    public void initInBean() {
        System.out.println("Bean內(nèi)自定義init——start——" + hashCode());

    }

    public void destroyInBean(){
        System.out.println("Bean內(nèi)自定義destroy——stop——" + hashCode());
    }

    public void defaultInit() {
        System.out.println("IoC全局默認(rèn)defaultInit——start——" + hashCode());
    }


    public void defaultDestroy(){
        System.out.println("IoC全局默認(rèn)defaultDestroy——stop——" + hashCode());
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("重寫接口afterPropertiesSet——start——" + hashCode());
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("重寫接口DisposableBean——stop" + hashCode());
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-init-method="defaultInit" default-destroy-method="defaultDestroy">

    <bean id="testInitial3" class="test4.TestInitial3" init-method="initInBean" destroy-method="destroyInBean"></bean>

 </beans>

測試后結(jié)果:

Paste_Image.png

發(fā)現(xiàn),三種初始化和銷毀方法同時執(zhí)行時夜惭,全局默認(rèn)的是不執(zhí)行的姻灶。其次,最先執(zhí)行的是接口诈茧。然后是bean內(nèi)自定義的产喉。
也就是三個優(yōu)先級為:接口>Bean中配置>全局默認(rèn)
其中全局默認(rèn)即使配置了,類里面不寫也不會報錯若皱,其他兩個疾瓮,則會報錯。


Aware

  • Spring中提供了一些以Aware結(jié)尾的接口疯趟,實現(xiàn)了Aware接口的bean在被初始化之后叭首,可以獲取相應(yīng)資源
  • 通過實現(xiàn)Aware接口,可以對Spring相應(yīng)資源進(jìn)行操作(一定要慎重)
  • 為對Spring進(jìn)行簡單的擴展互广,提供了方便的接口

Aware相關(guān)常用接口

  • ApplicationContextAware:實現(xiàn)了此接口的bean敛腌,可以獲取到當(dāng)前ApplicationContext的信息。這個類就可以方便獲得ApplicationContext中的所有bean惫皱。換句話說像樊,就是這個類可以直接獲取spring配置文件中,所有有引用到的bean對象旅敷。
  • BeanNameAware:實現(xiàn)了此接口的bean生棍,可以獲取到自己在IoC中的beanId。

以上接口媳谁,都是在bean初始化時候調(diào)用涂滴。

下面測試接口功能是否如上所述:

package test5;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * Created by amber on 2017/5/27.
 */
public class TestAware implements ApplicationContextAware, BeanNameAware {

    private String beanName;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext執(zhí)行時間戳:" + System.currentTimeMillis());
        System.out.println("獲取當(dāng)前bean的hashCode:" + applicationContext.getBean(beanName).hashCode());
    }

    @Override
    public void setBeanName(String name) {
        beanName = name;
        System.out.println("setBeanName執(zhí)行時間戳:" + System.currentTimeMillis());

    }
}

IoC容器中

<bean id="testAware" class="test5.TestAware"></bean>

單元測試中

 @Test
    public void testAware(){
        System.out.println("單元測試獲取bean的hashCode:"+getBean("testAware").hashCode());
    }

結(jié)果如下友酱。
為什么我要加時間戳呢,主要是為了看哪個回調(diào)會先執(zhí)行柔纵,經(jīng)過多次測試發(fā)現(xiàn)BeanNameAware的setBeanName(String name)會先執(zhí)行缔杉。

Paste_Image.png

Bean的自動裝配(AutoWiring)
為什么需要自動裝配?
其實目的很簡單搁料,是偷懶或详。自動裝配可以不用讓我們在IoC容器的Bean中聲明這些東西啦:

 <property name="testDao" ref="testDao"/>
 <constructor-arg name="testDao" ref="testDao"/>

關(guān)于Spring自動裝配可以參考:spring的自動裝配

本次講設(shè)置在<beans>根節(jié)點的全局:default-autowire

  • No:(默認(rèn))不自動裝配。Bean的引用必須用ref元素定義郭计。對于較大的部署不建議改變默認(rèn)設(shè)置霸琴,因為明確指定協(xié)作者能更好控制和維護(hù)系統(tǒng)。 在某種程度上昭伸,它記錄了系統(tǒng)的結(jié)構(gòu)沈贝。
  • byName:通過屬性名稱自動裝配。Spring會尋找相同名稱的bean并將其與屬性自動裝配勋乾。譬如宋下,如果bean的定義設(shè)置了根據(jù)名稱自動裝配, 并且包含了一個master 屬性(換句話說辑莫,它有setMaster(..)方法)学歧,Spring會尋找名為master的bean的定義,并用它來裝配屬性
  • byType:如果容器中存在一個與指定屬性類型相同的bean各吨,那么將與該屬性自動裝配枝笨。如果存在多個該類型的bean,將會拋出異常揭蜒,并指出不能使用byType自動裝配這個bean横浑。如果沒有找到相同類型的,什么也不會發(fā)生屉更。屬性不會被設(shè)置徙融。
  • Constructor:和byType類似,不同之處在于它應(yīng)用于構(gòu)造器參數(shù)瑰谜。如果在容器中沒有找到與構(gòu)造器參數(shù)類型一致的bean欺冀,就會拋出異常。

在測試之前呢萨脑,先把結(jié)構(gòu)拋出來:


4
Paste_Image.png
Paste_Image.png
Paste_Image.png

自動裝配之byName:要保證beanId和調(diào)用它的類屬性名稱一致隐轩。

Paste_Image.png
Paste_Image.png

自動裝配之byType:將IoC容器中AutoWiringDao的id去掉,只留下class渤早。

Paste_Image.png
Paste_Image.png

自動裝配之constructor:

Paste_Image.png
Paste_Image.png

Resource

  • 針對于資源文件的統(tǒng)一接口
  • Resources
    • UrlResource:URL對應(yīng)的資源职车,根據(jù)一個Url地址即可構(gòu)建
    • ClassPathResource:獲取類路徑下的資源文件
    • FieSystemResource:獲取文件系統(tǒng)里面的資源
    • ServletContextResource:ServletContext封裝的資源,用于訪問ServletContext環(huán)境下的資源
    • InputStreamResource:針對于輸入流封裝的資源
    • ByteArrayResource:針對于字節(jié)數(shù)封裝的資源

Resource Loader

  • ResourceLoader 接口是用來加載 Resource 對象的,換句話說悴灵,就是當(dāng)一個對象需要獲取 Resource 實例時军援,可以選擇實現(xiàn) ResourceLoader 接口。
  • spring 里所有的應(yīng)用上下文都是實現(xiàn)了 ResourceLoader 接口称勋,因此,所有應(yīng)用上下文都可以通過 getResource() 方法獲取 Resource 實例涯竟。

Resource Loader接口詳情:


Paste_Image.png

可以看到赡鲜,我們需要傳入一個location進(jìn)去,然后接口會返回一個對應(yīng)Resource給我們庐船。那么location這個值银酬,我們都可以傳哪樣的呢?

前綴 樣例 說明
classpath: classpath:com/myapp/config.xml 從類路徑加載
file: file:///data/config.xml 將其作為 URL 對象筐钟,從文件系統(tǒng)加載
http: http://myserver/logo.png 將其作為 URL 對象 加載
(none) /data/config.xml 取決于底層的 ApplicationContext

下面來測試:

使用classpath獲取資源

1.首先在resource文件夾下增加一個config.txt文件揩瞪。

Paste_Image.png

2.新建一個TesrResource類,并通過實現(xiàn)ApplicationContextAware接口獲取到ApplicationContext篓冲,然后傳入classpath:位置的地址得到目標(biāo)文件信息李破。

Paste_Image.png

3.IoC容器注冊bean


Paste_Image.png

4.測試

Paste_Image.png

5.結(jié)果

Paste_Image.png

使用file:獲取資源

1.修改TestResource類的resource方法

Paste_Image.png

2.測試結(jié)果:

Paste_Image.png

使用http:獲取資源

1.修改resource方法

Paste_Image.png

2.測試結(jié)果


Paste_Image.png

不使用前綴獲取資源

1.修改resource方法

Paste_Image.png

2.測試結(jié)果

Paste_Image.png

為什么沒有前綴也能獲取到我們想要的文件呢?

  • 當(dāng)你在指定應(yīng)用上下文調(diào)用 getResource() 方法時壹将,而指定的位置路徑又沒有包含特定的前綴嗤攻,spring 會根據(jù)當(dāng)前應(yīng)用上下文來決定返回哪一種類型 Resource。
  • 這個例子诽俯,我們ApplicationContext是通過ClassPathXmlApplicationContext獲取到的妇菱,所以返回的是ClassPathResource對象。類似的暴区,如果是通過實例 FileSystemXmlApplicationContext 實例調(diào)用的闯团,返回的是一個 FileSystemResource 對象;如果是通過 WebApplicationContext 實例的仙粱,返回的是一個 ServletContextResource 對象…… 如上所說房交,你就可以在指定的應(yīng)用上下中使用 Resource 實例來加載當(dāng)前應(yīng)用上下文的資源。

下一篇:Spring學(xué)習(xí)筆記(五伐割、Bean裝配(下))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末涌萤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子口猜,更是在濱河造成了極大的恐慌负溪,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件济炎,死亡現(xiàn)場離奇詭異川抡,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門崖堤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侍咱,“玉大人,你說我怎么就攤上這事密幔⌒ǜ” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵胯甩,是天一觀的道長昧廷。 經(jīng)常有香客問我,道長偎箫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任眉枕,我火速辦了婚禮速挑,結(jié)果婚禮上梗摇,老公的妹妹穿的比我還像新娘伶授。我一直安慰自己糜烹,他們只是感情好疮蹦,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著感论,像睡著了一般紊册。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芳绩,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天妥色,我揣著相機與錄音嘹害,去河邊找鬼吼拥。 笑死凿可,一個胖子當(dāng)著我的面吹牛枯跑,可吹牛的內(nèi)容都是我干的敛助。 我是一名探鬼主播纳击,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼堡赔!你這毒婦竟也來了设联?” 一聲冷哼從身側(cè)響起善已,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤离例,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宫蛆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥寇,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年辑甜,在試婚紗的時候發(fā)現(xiàn)自己被綠了衰絮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡猫牡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淌友,到底是詐尸還是另有隱情震庭,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布婿崭,位于F島的核電站渣磷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏授瘦。R本人自食惡果不足惜醋界,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望提完。 院中可真熱鬧物独,春花似錦、人聲如沸氯葬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帚称。三九已至官研,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闯睹,已是汗流浹背戏羽。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留楼吃,地道東北人始花。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓妄讯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親酷宵。 傳聞我的和親對象是個殘疾皇子亥贸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)浇垦,斷路器炕置,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評論 6 342
  • 什么是Spring Spring是一個開源的Java EE開發(fā)框架。Spring框架的核心功能可以應(yīng)用在任何Jav...
    jemmm閱讀 16,475評論 1 133
  • Spring容器高層視圖 Spring 啟動時讀取應(yīng)用程序提供的Bean配置信息男韧,并在Spring容器中生成一份相...
    Theriseof閱讀 2,820評論 1 24
  • 離鄉(xiāng)兩百日朴摊,有家不能回。 有如斷根草此虑,日日漸枯萎甚纲。 心疲目無光,皮皺臉如灰朦前。 苦盼十日期介杆,笑顏故鄉(xiāng)歸。 ...
    森垚閱讀 190評論 0 1