1. 程式人生 > >【Spring筆記三】Spring中Bean(XML方式裝配)

【Spring筆記三】Spring中Bean(XML方式裝配)

       我們可以把 Spring 看作一個大型的工廠,而 Spring 容器中的 Bean 就是該工廠的產品。要想使用這個工廠生產和管理Bean,就需要在配置檔案中告訴它需要哪些 Bean,以及需要使用何種方法將這些 Bean 裝配到一起。

 

首先,分清楚 JavaBean 和 Spring 中的 Bean 區別在哪裡,二者是兩個概念不同的東西

1.用處不同:傳統 javabean 

更多地作為值傳遞引數,而spring中的bean用處幾乎無處不在,任何元件都可以被稱為bean。

2.寫法不同:傳統 javabean 作為值物件,要求每個屬性都提供getter和setter方法;但spring中的bean只需為接受設值注入的屬性提供setter方法。

3.生命週期不同:傳統 javabean 作為值物件傳遞,不接受任何容器管理其生命週期;spring 中的 bean 有 spring 管理其生命週期行為。

總結:在 Spring 中,所有可以被 IOC容器 例項化並管理的 Java類 都可以稱為 Bean。


Spring 中 Bean 的裝配方式有兩種:XML 裝配和 註解 裝配,先說 XML 的方式,下節再寫註解裝配的方式

Bean的裝配(XML方式)

在Spring中,例項化Bean有三種方式,分別為 全類名配置(常用)工廠方法配置(靜態工廠方式 和例項工廠方式),配置Bean(基於FactoryBean)

由於第一種方法比較常用,這裡只寫第一種方法

準備一個 POJO

package com.how2java.pojo;
 
public class Product {
 
    private int id;
    private String name;
    private Category category;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Category getCategory() {
        return category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
}

然後通過 全類名配置 的方式配置 XML

<bean id="c" class="com.how2java.pojo.Category">
   <!--這種屬性注入方式會呼叫Category類中setName方法-->
   <property name="name" value="category 1" />
</bean>

<bean name="p" class="com.how2java.pojo.Product">
   <property name="name" value="product1" />
   <property name="category" ref="c" />
</bean>

注: 1)id 屬性 在 IOC 容器中指的是 Bean 的名稱,且在 IOC 容器中必須是唯一的; 
   2)如果 id 屬性和 name 都沒有指定,Spring 則會自動將 全類名(即class中的值) 作為 Bean 的名稱

name (指的是Bean的name)和 id 一樣,Spring都可以通過這這兩個屬性對容器中 Bean 進行配置和管理。不同的是,name屬性可以為 Bean 指定多個名稱,每個名稱用逗號或分好隔開,但Bean的 id 在 Spring 中卻是唯一的。

 

依賴注入(DI)的方式

在上面配置 XML 時,DI 用的是 屬性注入

<!--這種屬性注入方式會呼叫Category類中setName方法-->
   <property name="name" value="category 1" />

 這裡寫兩種比較 常用 的注入方式:

1.屬性注入(就如上面的程式碼)

2.構造器注入

    使用構造器注入屬性值時,可以指定引數的位置和引數的型別,以區分過載的構造器,它依賴於類中的 構造方法。

<bean id="car" class="com.sun.bean.Car">
    <constructor-arg value="Audi" index="0"></constructor-arg>
    <constructor-arg value="ShangHai" index="1"></constructor-arg>
    <constructor-arg value="203" type="int"></constructor-arg>
</bean>

呼叫的構造器如下:

public Car(String brand, String carp, int maxSpeed) {
    this.brand = brand;
    this.carp = carp;
    this.maxSpeed = maxSpeed;
}

 關於屬性注入的更多細節請參考:

https://blog.csdn.net/sun8112133/article/details/80192817


從IOC容器中獲取Bean

從 IOC 容器中獲取 Bean,呼叫的是 getBean() 方法,getBean() 方法是在 BeanFactory 介面中定義的,而 ApplicationContext 介面繼承了 BeanFactory 介面,它提供了BeanFactory所有功能,同時還以一種更加面向框架的方式增強了BeanFactory的功能,主要體現在Context包使用分層和有繼承關係的上下文類。

ApplicationContext在初始化上下文時就例項化所有單例的 Bean,也就是在建立 IOC 容器的時候就例項化所有的單例 Bean。

建立ApplicationContext介面例項,通常採用兩種方法

  • ClassPathXmlApplicationContext:從類路徑下載入 xml 配置檔案    (常用)
  • FileSystemXmlApplicationContext:從檔案系統中載入配置檔案

最常用的兩種獲取 Bean的方式

1.通過id獲取IOC中的Bean

Product p = (Product) context.getBean("p");

2.通過 全類名 獲取IOC容器中的Bean:

Product p = (Product) context.getBean(Product.class);
package com.how2java.test;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.how2java.pojo.Product;
 
public class TestSpring {
 
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });
 
        Product p = (Product) context.getBean("p");
 
        System.out.println(p.getName());
        System.out.println(p.getCategory().getName());
    }
}