1. 程式人生 > >Spring之Bean的建立和裝配

Spring之Bean的建立和裝配

前言

最近在重溫Spring,因此決定寫一系列的關於Spring學習的部落格,一是為了加深自己的理解,二來希望能幫助更多的朋友掌握Spring。我用到的Spring版本是3.1.1。

Spring建立Bean

Bean應該說是Spring中最基本的配置單位了,任何的操作都離不開Bean(好像是廢話哈)。記得剛開始接觸JavaEE的時候,看網上的教程通篇都是Bean啊Bean的,當時真是不知道Bean是何方神聖,英語不好還特意查了字典,發現Bean是豆子。。。這樣就更難理解了。在我的理解中Bean就是一個類,在Spring中通過元素宣告一個Bean,當合適的時候Spring容器來將這個Bean例項化,然後管理它的生命週期。

宣告Bean

宣告Bean很很簡單,首先在名稱空間中新增Bean的引用,一般類似下面這樣:

<?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"
>
</beans>

之後就可以在配置檔案中自由的定義Bean了(友情提示:使用IntelliJ IDEA新增相應的名稱空間後可以自動帶出能出現的元素)。
為了下面講解方便,我先寫兩個類–經典的員工Employee和部門Department:
Employee.java

public class Employee {
    private String name;
    private Date birthDate;
    private int level;

    public String getName() {
        return name;
    }

    public
void setName(String name) { this.name = name; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } }

Department .java

public class Department {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

上面已經新增過Bean的名稱空間了,因此我們就可以定義一個Employee和Department了:

<bean id="employee" class="com.stream.spring.bean.entity.Employee" />
<bean id="dept" class="com.stream.spring.bean.entity.Department" />

bean元素有幾個屬性值得注意:

  1. id或者name,指定Bean的名字。需要注意的是id是Bean的唯一標誌,而name可以有多個,並且在定義name的時候可以用任意的空格,逗號或者分號做分割。
  2. scope指定Bean的作用域。scope有五個可選值:singleton,prototype,request,session,global session。singleton是Spring預設的值,使用這個作用域的Bean,在容器中只有一個例項,從容器啟動,到第一次被請求而例項化開始,只要容器不銷燬或退出,該例項就會一直存活。prototype是多例項,對於每個請求都會返回一個例項。剩下的三個只適用於Web程式。
  3. init-method和destroy-method分別指定初始化方法和銷燬方法。全域性的初始化方法和銷燬方法在beans元素上定義default-init-method和default-destroy-method。
  4. factory-method通過工廠方法例項化Bean。
  5. autowire屬性指定Bean中屬性自動裝配時的查詢方式。

注入Bean的屬性

Spring注入Bean屬性有兩種方式:構造器注入和setter方法注入。

構造器注入

構造器注入使用constructor-arg標籤

<bean id="employee" class="com.stream.spring.bean.entity.Employee">
    <constructor-arg name="name" value="stream" index="0"/>
</bean>

name是構造器方法的引數,index是引數的位置,當注入的是Bean時可以使用ref屬性。當使用構造器方法注入的時候,constructor-arg列表個數要個構造方法的引數個數一致,如下:

    public Employee(String name,int level){
        this.name = name;
        this.level = level;
        System.out.println("name,level");
    }

    /*public Employee(String name){
        this.name = name;
        System.out.println("name");
    }*/
    public Employee(int level){
        this.level = level;
    }

在Employee的構造方法中沒有對應的只有一個引數的構造方法,這樣在例項化Bean的時候會報錯:

Unsatisfied dependency expressed through constructor argument with index 1 of type [int]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?

另外需要注意的是如果沒有無參構造方法,那麼在裝配Bean屬性的時候必須要有構造器注入,否則會報錯。

setter方法注入

setter方法注入使用property標籤:

<bean id="employee" class="com.stream.spring.bean.entity.Employee">
    <property name="name" value="Stream" />
</bean>

和構造器注入類似,name是Bean的屬性名,當需要注入Bean時可以用ref屬性。
setter方法只要保證在java類中有對應的setter方法即可,對順序和個數沒有限制。

裝配集合

當裝配的屬性是基本資料型別時可以直接使用value屬性,當引用其它Bean時使用ref屬性,當屬性是集合時Spring也提供了對應的方法。
Spring提供了4種類型的集合配置元素:

元素名稱 用途 宣告方式
list 裝配list型別的值,允許重複 list
set 裝配set型別的值,不允許重複 set
map 裝配map型別的值,key和value可以是任意型別 map
props 裝配properties型別的值,key和value必須都是String型別 props

裝配空值

可以使用標籤來顯式的指定空值。