一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務(wù)器之家 - 編程語言 - Java教程 - 詳解Spring中bean的幾種注入方式

詳解Spring中bean的幾種注入方式

2021-05-07 11:09Kevin.ZhangCG Java教程

這篇文章主要介紹了詳解Spring中bean的幾種注入方式,主要介紹了4種注入,主要有屬性注入、構(gòu)造函數(shù)注入、工廠方法注入,非常具有實(shí)用價(jià)值,需要的朋友可以參考下

首先,要學(xué)習(xí)spring中的bean的注入方式,就要先了解什么是依賴注入。依賴注入是指:讓調(diào)用類對(duì)某一接口的實(shí)現(xiàn)類的實(shí)現(xiàn)類的依賴關(guān)系由第三方注入,以此來消除調(diào)用類對(duì)某一接口實(shí)現(xiàn)類的依賴。

spring容器中支持的依賴注入方式主要有屬性注入、構(gòu)造函數(shù)注入、工廠方法注入。接下來將為大家詳細(xì)介紹這三種依賴注入的方式以及它們的具體配置方法。

1.屬性注入

屬性注入即通過setxxx( )方法注入bean的屬性值或依賴對(duì)象。由于屬性注入方式具有可選擇性和靈活性高的特點(diǎn),因此它也是實(shí)際開發(fā)中最常用的注入方式。

spring首先會(huì)調(diào)用bean的默認(rèn)構(gòu)造函數(shù)實(shí)例化bean對(duì)象,然后再通過反射的方法調(diào)用set方法來注入屬性值。

屬性注入要求bean提供一個(gè) 默認(rèn)的構(gòu)造函數(shù) ,并且得為需要注入的屬性提供 set方法 。

tips:所謂默認(rèn)的構(gòu)造函數(shù),即不帶參數(shù)的構(gòu)造函數(shù)。如果類中沒有自定義任何構(gòu)造函數(shù),則系統(tǒng)(jvm)會(huì)自動(dòng)生成一個(gè)不帶參的默認(rèn)構(gòu)造函數(shù),如果類中顯式的自定義了有參數(shù)的構(gòu)造函數(shù),則系統(tǒng)就不會(huì)在自動(dòng)生成默認(rèn)構(gòu)造函數(shù),需要自己手動(dòng)再加一個(gè)無參的構(gòu)造函數(shù)。

下面通過一個(gè)實(shí)例來演示spring中bean的屬性注入方式:

編寫一個(gè)user類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kevin.bean;
/**
 * 創(chuàng)建一個(gè)類測(cè)試bean的屬性注入方式
 * @author kevin
 *
 */
public class user { 
  private string username;
  public string getusername() {
    return username;
  }
 
  public void setusername(string username) {
    this.username = username;
  }
}

配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="user" class="com.kevin.bean.user">
    <property name="username">
      <value>kevin</value>
    </property>
  </bean> 
</beans>

其中,每個(gè)屬性值對(duì)應(yīng)一個(gè)property標(biāo)簽,name屬性值為類中屬性的名稱。在bean實(shí)現(xiàn)類中擁有與其對(duì)應(yīng)的實(shí)現(xiàn)方法setusername( )。

tips:spring只會(huì)檢查bean中是否含有setter方法,而對(duì)是否有對(duì)應(yīng)的屬性變量則不作具體要求,但按照約定俗成的規(guī)則我們最好為其設(shè)定相應(yīng)的屬性變量。

spring中<property>標(biāo)簽的命名規(guī)范:

  1. spring的<property>標(biāo)簽所指定的屬性名稱和bean實(shí)現(xiàn)類的setter方法滿足sun javabean的屬性命名規(guī)范,即xxx的屬性對(duì)應(yīng)setxxx( )的方法。

一般情況下,java的屬性變量名都以小寫字母開頭,但考慮到一些特殊意義的英文縮略詞,java bean也允許一些大寫字母開頭的變量名。但必須滿足以下兩點(diǎn):

  1. 變量的前兩個(gè)字母要么全部大寫,要么全部小寫;
  2. 但以一般編程習(xí)慣來說,屬性名最好全部使用小寫字母,方便編程和閱讀。

對(duì)于屬性注入方式來說,只能人為的在配置文件中提供保證,而無法在語法級(jí)別提供保證。此時(shí)就需要使用構(gòu)造函數(shù)注入這種方式,以此來更好的滿足要求。

2.構(gòu)造函數(shù)注入

構(gòu)造函數(shù)注入是除屬性注入之外的另一種常用的注入方式,它可以保證一些必要的屬性在bean實(shí)例化時(shí)就得到了設(shè)置,并在實(shí)例化后就可以使用。

使用構(gòu)造函數(shù)注入的前提是: bean必須提供帶參的構(gòu)造函數(shù)。

對(duì)于構(gòu)造函數(shù)的注入,配置文件可以有以下幾種方式:

  1. 按類型匹配入?yún)?/li>
  2. 按索引匹配入?yún)?/li>
  3. 聯(lián)合使用類型和索引匹配入?yún)?/li>
  4. 通過自身類型反射匹配入?yún)?/li>

【按類型匹配入?yún)⒎绞健?/strong>

編寫bean代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.kevin.bean;
/**
 * 編寫bean測(cè)試按類型匹配入?yún)⒎绞?/code>
 * @author kevin
 *
 */
public class person {
  private string name;
  private integer age;
  public string getname() {
    return name;
  }
  public void setname(string name) {
    this.name = name;
  }
  public integer getage() {
    return age;
  }
  public void setage(integer age) {
    this.age = age;
  }
}

編寫配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="person" class="com.kevin.bean.person">
    <constructor-arg type="string">
      <value>kevin</value>
    </constructor-arg>
    <constructor-arg type="integer">
      <value>20</value>
    </constructor-arg>
  </bean> 
</beans>

spring的配置文件采用和元素標(biāo)簽順序無關(guān)的配置策略,因此可以在一定程度上保證配置信息的確定性。

那么當(dāng)bean中的構(gòu)造函數(shù)的 多個(gè)類型參數(shù)一樣時(shí) ,按照類型匹配入?yún)⒌倪@種方式容易產(chǎn)生混淆,此時(shí)就需要使用另一種方式:按照索引匹配入?yún)ⅰ?/p>

【按照索引匹配入?yún)ⅰ?/strong>

編寫bean代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kevin.bean;
/**
 * 編寫bean測(cè)試按照索引方式入?yún)?/code>
 * @author kevin
 *
 */
public class student {
  private string name;
  private string gender;
  private double score;
  public student(string name, string gender, double score) {
    super();
    this.name = name;
    this.gender = gender;
    this.score = score;
  }
}

配置文件編寫如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="student" class="com.kevin.bean.student">
    <constructor-arg index="0" value="kevin"></constructor-arg>
    <constructor-arg index="1" value="male"></constructor-arg>
    <constructor-arg index="2" value="66"></constructor-arg>
  </bean> 
</beans>

tips: 在屬性注入時(shí),spring按java bean的規(guī)范確定配置 屬性 和對(duì)應(yīng)的 setter方法 ,并使用java反射機(jī)制調(diào)用屬性的setter方法完成屬性注入。但java反射機(jī)制并 不會(huì)記住構(gòu)造函數(shù)的入?yún)⒚?,因此我們不能通過制定構(gòu)造函數(shù)的入?yún)⒚Q來進(jìn)行構(gòu)造函數(shù)的配置,所以我們只能通過 入?yún)⒌念愋图八饕?來間接完成構(gòu)造函數(shù)的屬性注入。

【聯(lián)合使用類型和索引匹配入?yún)ⅰ?/strong>

在某些復(fù)雜的配置文件當(dāng)中,需要使用type和index同時(shí)出馬才能完成構(gòu)造函數(shù)的參數(shù)注入。下面使用一個(gè)實(shí)例來演示。

編寫bean:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.kevin.bean;
/**
 * 編寫bean測(cè)試聯(lián)合使用類型和索引匹配入?yún)?/code>
 * @author kevin
 *
 */
public class teacher {
  private string name;
  private string address;
  private double salary;
  private int age;
  public teacher(string name, string address, double salary) {
    super();
    this.name = name;
    this.address = address;
    this.salary = salary;
  }
  public teacher(string name, string address, int age) {
    super();
    this.name = name;
    this.address = address;
    this.age = age;
  }
}

在這個(gè)類中,有兩個(gè)重載的構(gòu)造函數(shù),他們都有三個(gè)參數(shù),在這種情況下使用type和index的方法都不能完成要求,這時(shí)候就需要他們兩個(gè)屬性同時(shí)使用了。

配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="teacher" class="com.kevin.bean.teacher">
    <constructor-arg index="0" type="string">
      <value>kevin</value>
    </constructor-arg>
    <constructor-arg index="1" type="string">
      <value>china</value>
    </constructor-arg>
    <constructor-arg index="2" type="int">
      <value>20</value>
    </constructor-arg>
  </bean> 
</beans>

可以看到其實(shí)重點(diǎn)在于第三個(gè)入?yún)⒌念愋停晕覀冊(cè)谂渲梦募兄付怂饕皖愋停@樣便可以使得spring知道對(duì)哪個(gè)構(gòu)造函數(shù)進(jìn)行參數(shù)注入了。

tips: 加入我們得配置文件中存在歧義問題,spring容器是可以正常啟動(dòng)的,并不會(huì)報(bào)錯(cuò),它將隨機(jī)采用一個(gè)匹配的構(gòu)造函數(shù)實(shí)例化bean。而隨機(jī)選擇的構(gòu)造函數(shù)可能并不是用戶所需要的,所以我們?cè)诰幊虝r(shí)要小心避免出現(xiàn)這種歧義情況。

【通過自身類型反射匹配入?yún)ⅰ?/strong>

如果bean構(gòu)造函數(shù)入?yún)⒌念愋褪强杀鎰e的,由于java反射機(jī)制可以獲取構(gòu)造函數(shù)入?yún)⒌念愋停词箻?gòu)造函數(shù)的注入不提供類型和索引的信息,spring依舊可以完成構(gòu)造函數(shù)信息的注入。例如下面實(shí)例中manager類的構(gòu)造函數(shù)的入?yún)㈩愋途褪强梢员鎰e的。

編寫manager類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.kevin.bean;
/**
 * 編寫bean測(cè)試通過自身類型反射匹配入?yún)⒎绞?/code>
 * @author kevin
 *
 */
public class manager {
  private string name;
  private double salary;
  private person person;
  public manager(string name, double salary, person person) {
    super();
    this.name = name;
    this.salary = salary;
    this.person = person;
  }
}

編寫配置文件:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="manager" class="com.kevin.bean.manager">
    <constructor-arg>
      <value>kevin</value>
    </constructor-arg>
    <constructor-arg>
      <ref bean="user"/>
    </constructor-arg>
    <constructor-arg>
      <ref bean="person"/>
    </constructor-arg>
  </bean> 
</beans>

以上幾種方法都可以實(shí)現(xiàn) 構(gòu)造函數(shù)參數(shù)的注入 ,但是為了避免問題的發(fā)生,還是建議使用 顯式的index和type 來配置構(gòu)造函數(shù)的入?yún)⑿畔ⅰ?/p>

3.工廠方法注入

工廠方法是應(yīng)用中被經(jīng)常使用的設(shè)計(jì)模式,也是 控制反轉(zhuǎn) 和 單實(shí)例設(shè)計(jì)思想 的主要實(shí)現(xiàn)方法。工廠類負(fù)責(zé)創(chuàng)建一個(gè)或多個(gè)工廠類實(shí)例,工廠類方法一般以接口或抽象類變量的形式返回目標(biāo)類實(shí)例。

工廠類對(duì)外屏蔽了目標(biāo)類的實(shí)例化步驟,調(diào)用者甚至根本不用指定具體的目標(biāo)類是什么。由于spring容器以框架的方法提供工廠方法的功能,并以透明的方式開放給開發(fā)者。因此很少需要手工編寫工程方法。但在一些遺留系統(tǒng)或第三方類庫(kù)中還是會(huì)碰到工程方法,此時(shí)便可以使用spring工廠注入的方法來進(jìn)行spring的注入。

spring工廠注入的方法可以分為 靜態(tài) 和 非靜態(tài) 兩種。

【非靜態(tài)工廠方法】

有些工廠方法是非靜態(tài)的,必須實(shí)例化工廠類之后才能調(diào)用工廠方法。下面通過一個(gè)實(shí)例來演示。

編寫工廠類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.kevin.factorybean;
/**
 * 編寫工廠類測(cè)試非靜態(tài)工廠方法注入
 * @author kevin
 *
 */
 
public class bookfactory {
  public book buybook(){
    book book = new book();
    book.setname("think in java");
    return book;
  }
}

配置文件編寫:

?
1
2
3
4
5
6
7
8
9
10
11
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="bookfactory" class="com.kevin.factorybean.bookfactory"></bean>
  <bean id="book" factory-bean="bookfactory" factory-method="buybook"></bean>
  </beans>

由于bookfactory的工廠方法不是靜態(tài)的,因此需要先定義一個(gè)工廠類的bean,然后通過 factory-bean 屬性來引用工廠bean實(shí)例。再通過屬性 factory-method 來指定對(duì)應(yīng)的工廠方法。

【靜態(tài)工廠方法】

很多工廠類方法都是靜態(tài)的,這意味著無需創(chuàng)建工廠類實(shí)例的情況下就可以調(diào)用工廠類方法。因此靜態(tài)工程方法比非靜態(tài)工廠方法的調(diào)用更加方便簡(jiǎn)潔。下面通過一個(gè)實(shí)例來演示靜態(tài)工廠方法。

編寫factory類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.kevin.factorybean;
/**
 * 編寫工廠類測(cè)試靜態(tài)工廠方法注入
 * @author kevin
 *
 */
public class carfactory {
  public static car createcar(){
    car car = new car();
    car.setbrand("lamborghini");
    return car;
  }
}

編寫配置文件:

?
1
2
3
4
5
6
7
8
9
10
<?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"> <!-- bean definitions here -->
 
  <!-- 配置對(duì)象 -->
  <bean id="car" class="com.kevin.factorybean.car" factory-method="createcar"></bean> 
</beans>

總結(jié)

spring提供了三種可供選擇的注入方式,但在實(shí)際應(yīng)用中,我們究竟該選擇哪種注入方式,并沒有統(tǒng)一的標(biāo)準(zhǔn),如下是一些可以參考的理由:

構(gòu)造函數(shù)注入理由:

  1. 構(gòu)造函數(shù)保證重要屬性預(yù)先設(shè)置;
  2. 無需提供每個(gè)屬性的setter方法,減少類的方法個(gè)數(shù);
  3. 可以更好地封裝類變量,避免外部錯(cuò)誤調(diào)用。

屬性注入理由:

  1. 屬性過多時(shí),構(gòu)造函數(shù)變的臃腫;
  2. 構(gòu)造函數(shù)注入靈活性不強(qiáng),有時(shí)需要為屬性注入null值;
  3. 多個(gè)構(gòu)造函數(shù)時(shí),配置上產(chǎn)生歧義,復(fù)雜度升高;
  4. 構(gòu)造函數(shù)不利于類的繼承和擴(kuò)展;
  5. 構(gòu)造函數(shù)注入會(huì)引起循環(huán)依賴的問題。 

其實(shí)spring為我們注入?yún)?shù)提供了這么多方法,那么這些方法必然有他們存在的道理,每個(gè)方法在某一問題上會(huì)有獨(dú)特的優(yōu)勢(shì),我們只需要按照我們具體的使用需求選擇適合的方法來使用就好了,但一般不太推薦工廠方法注入。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/Kevin-ZhangCG/p/9080183.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品久久久久影院色老大 | 亚洲精品成人456在线播放 | 美女的隐私无遮挡的网页 | 啊啊啊好大好爽视频 | 精品亚洲午夜久久久久 | 60岁妇女毛片免费观看 | 青青草一区二区免费精品 | 97视频免费人人观看人人 | 狠狠色伊人亚洲综合网站色 | 91桃色视频| 手机看片福利盒子久久 | 日韩高清无砖砖区2022 | 深夜精品高中女学生 | 色综合九九 | 耽美肉文高h | 国产成人精品视频一区二区不卡 | 热巴在公交车h文 | 好吊色永久免费视频大全 | 欧美视频精品一区二区三区 | 婷婷色天使在线视频观看 | 九色PORNY蝌蚪视频首页 | 亚洲女人国产香蕉久久精品 | 免费一级日本c片完整版 | 亚洲gogo人体大胆西西安徽 | 亚洲激情在线 | 欧美性受xxxx88喷潮 | 青青热久免费精品视频网站 | 高清不卡日本v在线二区 | 亚洲欧美精品久久 | 国产午夜亚洲精品不卡 | 9久re热视频这里只有精品 | 女色在线观看免费视频 | 国产永久免费爽视频在线 | 久久免费资源福利资源站 | 亚洲国产精久久久久久久 | 亚洲国产综合久久久无码色伦 | 国产精品久久久久久久久免费 | 99热这里只有精品久久免费 | 国产福利专区精品视频 | 欧美一级片在线视频 | 桃花岛在线 |