1. 程式人生 > >Spring 學習筆記(二)- Bean 的配置

Spring 學習筆記(二)- Bean 的配置

# 概要
  • IOC & DI 概述
  • 配置 bean
  • 配置形式:基於 XML 檔案的方式;基於註解的方式
  • Bean 的配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法 & 例項工廠方法)、FactoryBean
  • IOC 容器 BeanFactory & ApplicationContext - - 概述
  • 依賴注入的方式:屬性注入;構造器注入
  • 注入屬性值細節
  • 自動轉配
  • bean 之間的關係:繼承;依賴
  • bean 的作用域:singleton;prototype;WEB 環境作用域
  • 使用外部屬性檔案
  • spEL
  • IOC 容器中 Bean 的生命週期
  • Spring 4.x 新特性:泛型依賴注入

IOC 和 DI

  • IOC(Inversion of Control):其思想是反轉資源獲取的方向. 傳統的資源查詢方式要求元件向容器發起請求查詢資源. 作為迴應, 容器適時的返回資源. 而應用了 IOC 之後, 則是容器主動地將資源推送給它所管理的元件, 元件所要做的僅是選擇一種合適的方式來接受資源. 這種行為也被稱為查詢的被動形式
  • DI(Dependency Injection) — IOC 的另一種表述方式:即元件以一些預先定義好的方式(例如: setter 方法)接受來自如容器的資源注入
    . 相對於 IOC 而言,這種表述更直接

具體設計

Car 類設計

package www.xq.spring.beans;
public class Car {

	private String brand;
	private String crop;
	private double price;
	private int maxSpeed;

	public Car(String brand, String crop, double price) {
		super();
		this.brand = brand;
		this.crop = crop;
		this.price =
price; } public Car(String brand, String crop, int maxSpeed) { super(); this.brand = brand; this.crop = crop; this.maxSpeed = maxSpeed; } public String toString() { return "Car [brand=" + brand + ", crop=" + crop + ", price=" + price + ", maxSpeed=" + maxSpeed + "]"; } public void setPrice(double price) { this.price = price; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } }

Person 類設計

package www.xq.spring.beans;

public class Person {

	private String name;
	private int age;

	private Car car;

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Car getCar() {
		return car;
	}

	public void setCar(Car car) {
		this.car = car;
	}

	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
	}

	public Person() {
		super();
	}

	public Person(String name, int age, Car car) {
		super();
		this.name = name;
		this.age = age;
		this.car = car;
	}

}

Spring 配置檔案 applicationContext.xml

<!-- 配置 bean class:bean 的全類名,通過反射的方式在 IOC 容器中建立 Bean.所以要求 Bean 中必須有無引數的構造器 
		id:標識容器中的 bean.id 唯一. -->

<!-- 通過構造方法來配置 bean 的屬性 -->
	<bean id="car" class="www.xq.spring.beans.Car">
		<constructor-arg value="Audi" index="0"></constructor-arg>
		<constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg>
		<constructor-arg value="500000" type="double"></constructor-arg>
	</bean>

<!-- 使用構造器注入屬性值可以指定引數的位置和引數的型別!以區分過載的構造器! -->
	<bean id="car2" class="www.xq.spring.beans.Car">
		<constructor-arg value="BaoMa" type="java.lang.String"></constructor-arg>
		<!-- 如果字面上包含特殊字元可以使用 <![CDATA[]]> 包裹起來 -->
		<!-- 屬性值也可以使用 value 子節點進行配置 -->
		<constructor-arg index="1">
			<value><![CDATA[<shanghai^>]]></value>
		</constructor-arg>
		<constructor-arg type="int">
			<value>250</value>
		</constructor-arg>
	</bean>
	
	<bean id="person" class="www.xq.spring.beans.Person">
		<property name="name" value="Tom"></property>
		<property name="age" value="24"></property>
		<!-- 可以使用 property 的 ref 屬性建立 bean 之間的引用關係 -->
		<!-- <property name="car" ref="car2"></property> -->
		<!-- <property name="car"> <ref bean="car2"/> </property> -->
		
		<!-- 內部 bean,不能被外部引用. 只能在內部使用 -->
		<property name="car">
			<bean class="www.xq.spring.beans.Car">
				<constructor-arg value="Ford"></constructor-arg>
				<constructor-arg value="Changan"></constructor-arg>
				<constructor-arg value="200000" type="double"></constructor-arg>
			</bean>
		</property>
		<property name="car.maxSpeed" value="260"></property>
	</bean>

	<bean id="person2" class="www.xq.spring.beans.Person">
		<constructor-arg value="Jerry"></constructor-arg>
		<constructor-arg value="25"></constructor-arg>
		<!-- <constructor-arg ref="car"></constructor-arg> -->
		<!-- 測試賦值 null -->
		<!-- 可以自己測試 -->
		<!-- <constructor-arg><null/></constructor-arg> -->
		
		<constructor-arg ref="car"></constructor-arg>
		<!-- 為級聯屬性賦值. 注意:屬性需要先初始化後才可以為級聯屬性賦值.否則會有異常,和 Struts2不同. -->
		<property name="car.maxSpeed" value="300"></property>
	</bean>

main 函式設計


public static void main(String[] args) {
		
		// 1. 建立 Sring 的 IOC 容器物件
		// ApplicationContext 代表 IOC 容器
		// ClassPathXmlApplicationContext:是 ApplicationContext 介面的實現類.該實現類從類路徑下來載入配置檔案.
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"applicationContext.xml");

		// 2. 從 IOC 容器中獲取 Bean 例項
		//利用  id 定位到 IOC 容器中的 bean
		Car car = (Car) ctx.getBean("car");
		System.out.println(car);
		//利用型別返回 IOC 容器中的 Bean,但要求 IOC 容器中必須只能有一個該型別的 Bean
        
		car = (Car) ctx.getBean("car2");
		System.out.println(car);
		
		Person person = (Person) ctx.getBean("person");
		System.out.println(person);
		
		person = (Person) ctx.getBean("person2");
		System.out.println(person);
		
	} 

學習總結

基本內容

  1. BeanFactory:IOC 容器的基本實現.
  2. ApplicationContext: 提供了更多的高階特性. 是 BeanFactory 的子介面.
  3. BeanFactory 是 Spring 框架的基礎設施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的開發者,幾乎所有的應用場合都直接使用 ApplicationContext 而非底層的 BeanFactory
  4. 配置 bean class:bean 的全類名,通過反射的方式在 IOC 容器中建立 Bean.所以要求 Bean 中必須有無引數的構造器
    id:標識容器中的 bean.id 唯一.

依賴注入的方式

  • 依賴注入
    • 屬性注入

      • 屬性注入即通過 setter 方法注入Bean 的屬性值或依賴的物件
      • 屬性注入使用 元素, 使用 name 屬性指定 Bean 的屬性名稱,value 屬性或 子節點指定屬性值
      • 屬性注入是實際應用中最常用的注入方式
    • 構造器注入

      • 通過構造方法注入Bean 的屬性值或依賴的物件,它保證了 Bean 例項在例項化後就可以使用。
      • 構造器注入在 元素裡宣告屬性, 中沒有 name 屬性