1. 程式人生 > >Spring注入Bean的幾種方式

Spring注入Bean的幾種方式

首先,Bean的概念需要清晰:
Bean是一種符合一定要求的Java類
1 有預設的建構函式
2 對於私有屬性,有setter和getter

滿足了上述的條件,在工程中就可以在XML檔案中定義類的例項。一開始我不是很理解,為什麼要在XML中去定義例項,而不是正正常常的程式碼中建立。後來看了一些資料,敲了一些sample程式碼,看了一下《Spring實戰》,或多或少有一點理解。在實際變成中,我們需要實現多型,主要用到繼承和介面。一般開發中提倡“面向介面程式設計”,從而降低程式碼的藕合度。所以Spring的思想中,把類的例項化抽取出來,而程式碼中只需要做核心的邏輯實現。類的例項化在Spring裡面稱為wiring(裝配)或者inject(注入)。咋一看,裝配這個詞十分唬人,實際上就是把類例項化,然後把一些引數“塞”到這個物件裡面,同時把這個物件和別的物件的依賴關係一併搞清楚,如誰是誰的私有屬性之類的。

通過學習,我個人歸納了一下Spring裡面所謂的“依賴注入”的幾種方式。
1 完全通過XML檔案裝配
2 用Annotation自動裝配
3 用Java裝配
4 還有一些不倫不類的,介於使用XML和使用Annotation之間的做法,不提倡

第一步,配置XML檔案

首先,無論用何種方式裝配,都至少需要一個XML檔案,做一些基礎的調起啟動
新建一個XML檔案,樣式如下

<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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "
> ... add bean here... using <bean></bean> </beans>

<完全通過XML檔案裝配>

新建一個XML檔案,樣式如下

<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-2.5.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">

    <bean id="charlie" class="com.hunter.PoeticJuggler">
        <constructor-arg value = "25"/>
        <constructor-arg ref = "jingyesi"/>
    </bean>

    <bean id="jane" class = "com.hunter.Instrumentalist">
        <property name = "song" value="Jingle Bells"/>
    </bean>

</beans>

其中用來標寫JavaBean的內容,id最好是工程內的唯一,或者至少是package裡面的唯一。id就會去尋找class引數所示的類定義,然後例項化這個類。要使用這個物件,就需要在Java程式碼裡面用getBean。

<用Annotation裝配>

把XML檔案裡面的bean刪掉。咱們開始用Annotation來實現自動裝配。
Annotation指的是Java程式碼裡面,用@開頭的一些關鍵詞。
一般Spring是預設ban掉這個功能的。所以需要在XML檔案裡面新增一些東西。如下。
<context:annotation-config>

然後在Java程式碼裡面,就可以用一些關鍵詞去自動裝配了。Spring裡面使用@Autowired,例如:

public class Instrumentalist implements Performer{
    private Instrument instrument;

    @Autowired
    public void setInstrument(Instrument instrument){
        this.instrument = instrument;
    }
}

這裡,Autowired就自動把Instrument這個類例項化了。實際上有了這個Annotation都可以不需要下面那個setter函式。
假如Autowired寫在屬性上面,也是可行的做法,而且那樣還可以省去setter,如

public class Instrumentalist implements Performer{
    @Autowired
    private Instrument instrument;
    }
}

實際上這裡的Autowired是有比較大的侷限性的。實際使用的時候估計要對自動裝配做一下限定。

除了這種方法, 還有一種更狠的自動裝配,也叫自動監測。首先XML檔案中寫入這麼一句
<context:component-scan>
然後Spring會自動檢測程式碼中含有關鍵字@Component的class,然後註冊成為bean,id為類名,如

@Component
public class Instrumentalist implements Performer{

    public  Instrumentalist(){

    }
    public void perform(){
        System.out.println("Playing "+song+" : ");
        instrument.play();
    }
}

注意一點,這個類裡面必須要用預設建構函式,否則會報錯。JavaBean的要求正是有預設建構函式。
如果希望這個bean的名字是自己命名的,則可以寫成
@Component("Charlie")
則bean註冊id為charlie

<基於Java的裝配>

因為某些原因,有人很討厭尖括號的XML配置。所以Spring也提供了基於Java的配置方法。
不過,還是要在XML檔案裡面,加入這麼一句話。
<context:component-scan base-package=“com.hunter">
後面的base-package是所在的包名,
然後新建一個Java類,如下

package com.hunter;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig{
    @Bean
    public Performer duke(){
        return new Juggler();
    }
}

其中@Bean意味著接下來是一個bean的定義
Performer是返回的類
duke相當於id

小結:
作為初學者,不好客觀評價各種注入的方式,只能提一提個人的直覺。
第一種顯式定義bean顯然比較粗暴,實際開發中估計不建議這麼做,因為顯式定義將產生冗長的XML檔案,根本不便於維護;第二種方式程式碼上看比較不錯,程式碼簡單,不過同時可讀性相對弱一點,只有理解了bean注入的開發者才能體會程式碼,而且一旦不慎容易裝配錯誤;第三種做法比較有意思,不過有點失去Spring精髓的味道,感覺Spring的開發還是有點尖括號比較有feel。。嗯。。走題了~然而現在有一個叫做SpringBoot的專案,基本上就不需要任何XML檔案,變為需要記住不少Annotation。不過Annotation的確很有好處,起碼編譯器可以幫助我們報錯,如果是XML檔案,經常出錯了還找不到出錯的點,就比較麻煩。