最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年06月02日 15:04:29   作者:Kevin.ZhangCG  
這篇文章主要介紹了詳解Spring中bean的幾種注入方式,主要介紹了4種注入,主要有屬性注入、構(gòu)造函數(shù)注入、工廠方法注入,非常具有實用價值,需要的朋友可以參考下

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

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

1.屬性注入

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

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

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

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

下面通過一個實例來演示Spring中bean的屬性注入方式:

編寫一個user類:

package com.Kevin.bean;
/**
 * 創(chuàng)建一個類測試bean的屬性注入方式
 * @author Kevin
 *
 */
public class User {  
  private String username;
  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }
}

配置文件:

<?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 -->

  <!-- 配置對象 -->
  <bean id="user" class="com.Kevin.bean.User">
    <property name="username">
      <value>Kevin</value>
    </property>
  </bean>  
</beans>

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

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

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

  1. Spring的<property>標(biāo)簽所指定的屬性名稱和bean實現(xiàn)類的setter方法滿足Sun JavaBean的屬性命名規(guī)范,即XXX的屬性對應(yīng)setXXX( )的方法。

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

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

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

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

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

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

對于構(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代碼:

package com.Kevin.bean;
/**
 * 編寫bean測試按類型匹配入?yún)⒎绞?
 * @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;
  }
}

編寫配置文件:

<?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 -->

  <!-- 配置對象 -->
  <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ù)的 多個類型參數(shù)一樣時 ,按照類型匹配入?yún)⒌倪@種方式容易產(chǎn)生混淆,此時就需要使用另一種方式:按照索引匹配入?yún)ⅰ?/p>

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

編寫bean代碼:

package com.Kevin.bean;
/**
 * 編寫bean測試按照索引方式入?yún)?
 * @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;
  }
}

配置文件編寫如下:

<?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 -->

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

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

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

編寫bean:

package com.Kevin.bean;
/**
 * 編寫bean測試聯(lián)合使用類型和索引匹配入?yún)?
 * @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òu)造函數(shù),他們都有三個參數(shù),在這種情況下使用type和index的方法都不能完成要求,這時候就需要他們兩個屬性同時使用了。

配置文件:

<?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 -->

  <!-- 配置對象 -->
  <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>

可以看到其實重點在于第三個入?yún)⒌念愋?,所以我們在配置文件中指定了索引和類型,這樣便可以使得Spring知道對哪個構(gòu)造函數(shù)進行參數(shù)注入了。

Tips: 加入我們得配置文件中存在歧義問題,Spring容器是可以正常啟動的,并不會報錯,它將隨機采用一個匹配的構(gòu)造函數(shù)實例化bean。而隨機選擇的構(gòu)造函數(shù)可能并不是用戶所需要的,所以我們在編程時要小心避免出現(xiàn)這種歧義情況。

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

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

編寫Manager類:

package com.Kevin.bean;
/**
 * 編寫B(tài)ean測試通過自身類型反射匹配入?yún)⒎绞?
 * @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;
  } 
}

編寫配置文件:

<?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 -->

  <!-- 配置對象 -->
  <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>

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

3.工廠方法注入

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

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

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

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

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

編寫工廠類:

package com.Kevin.factorybean;
/**
 * 編寫工廠類測試非靜態(tài)工廠方法注入
 * @author Kevin
 *
 */

public class BookFactory {
  public Book buyBook(){
    Book book = new Book();
    book.setName("Think in Java");
    return book;
  }
}

配置文件編寫:

<?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 -->

  <!-- 配置對象 -->
  <bean id="bookFactory" class="com.Kevin.factorybean.BookFactory"></bean>
  <bean id="book" factory-bean="bookFactory" factory-method="buyBook"></bean>
  </beans>

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

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

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

編寫factory類:

package com.Kevin.factorybean;
/**
 * 編寫工廠類測試靜態(tài)工廠方法注入
 * @author Kevin
 *
 */
public class CarFactory {
  public static Car createCar(){
    Car car = new Car();
    car.setBrand("Lamborghini");
    return car;
  }
}

編寫配置文件:

<?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 -->

  <!-- 配置對象 -->
  <bean id="car" class="com.Kevin.factorybean.Car" factory-method="createCar"></bean>  
</beans>

總結(jié)

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

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

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

屬性注入理由:

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

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis打印的sql日志不寫入到log文件的問題及解決

    mybatis打印的sql日志不寫入到log文件的問題及解決

    這篇文章主要介紹了mybatis打印的sql日志不寫入到log文件的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Netty分布式ByteBuf使用SocketChannel讀取數(shù)據(jù)過程剖析

    Netty分布式ByteBuf使用SocketChannel讀取數(shù)據(jù)過程剖析

    這篇文章主要為大家介紹了Netty源碼分析ByteBuf使用SocketChannel讀取數(shù)據(jù)過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • java應(yīng)用領(lǐng)域分析

    java應(yīng)用領(lǐng)域分析

    在這篇文章里,我們將更確切地知道哪種類型的項目是使用Java完成的,Java運用在哪些主要領(lǐng)域和部門,以及Java在現(xiàn)實世界的哪些地方起著什么作用,需要的朋友可以參考下
    2017-09-09
  • Spring?Security如何實現(xiàn)升級密碼加密方式詳解

    Spring?Security如何實現(xiàn)升級密碼加密方式詳解

    這篇文章主要為大家介紹了Spring?Security實現(xiàn)升級密碼加密方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Java中判斷對象是否為空的不同方法

    Java中判斷對象是否為空的不同方法

    在Java編程中,經(jīng)常會遇到判斷對象是否為空的情況,本篇將深入探討Java中判斷對象是否為空的不同方法,包括使用條件判斷、使用Java 8的Optional類、使用Apache Commons Lang庫等,通過詳細的解釋和舉例說明,幫助讀者正確處理空對象問題,需要的朋友一起看看吧
    2023-11-11
  • IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大)

    IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大

    這篇文章主要介紹了IntelliJ IDEA 2021.1 推出語音、視頻功能,邊寫代碼邊聊天(功能超級強大),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java并發(fā)編程多線程間的同步控制和通信詳解

    Java并發(fā)編程多線程間的同步控制和通信詳解

    這篇文章主要為大家介紹了Java并發(fā)編程多線程間的同步控制和通信詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Java+Swing實現(xiàn)五子棋游戲的示例代碼

    Java+Swing實現(xiàn)五子棋游戲的示例代碼

    本文將通過Java語言實現(xiàn)經(jīng)典游戲—五子棋游戲,文中采用了Swing制作游戲界面,具有開始游戲,悔棋,認(rèn)輸,退出等功能。感興趣的可以跟隨小編一起動手試一試
    2022-02-02
  • java實現(xiàn)對對碰小游戲

    java實現(xiàn)對對碰小游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)對對碰小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • springmvc常用注解標(biāo)簽詳解

    springmvc常用注解標(biāo)簽詳解

    本篇文章主要介紹了springmvc常用注解標(biāo)簽詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07

最新評論

元朗区| 镇平县| 乌鲁木齐市| 连南| 古田县| 阿瓦提县| 武汉市| 彭山县| 纳雍县| 祁门县| 横山县| 六枝特区| 石楼县| 阿巴嘎旗| 肇源县| 正蓝旗| 冀州市| 鹤岗市| 靖安县| 南城县| 容城县| 秦安县| 邵东县| 辽宁省| 安新县| 重庆市| 封开县| 五常市| 凌云县| 鸡东县| 东莞市| 五大连池市| 滨州市| 开江县| 海城市| 潍坊市| 甘孜| 麻城市| 夏河县| 长宁区| 阜宁县|