Spring Bean教程

目錄:



配置形式

基於XML文件的形式

id:Bean 的名稱。
在 IOC 容器中必須是唯一的
若 id 沒有指定,Spring 自動將權限定性類名作爲 Bean 的名字
id 可以指定多個名字,名字之間可用逗號、分號、或空格分隔

<!-- 配置一個 bean -->
    <bean id="helloWorld" class="com.spring.helloworld.HelloWorld">
        <!-- 爲屬性賦值 -->
        <property name="user" value="Jerry"></property>
    </bean>

基於註解的方式

組件掃描(component scanning):Spring能夠從classpath下自動掃描,偵測和實例化具有特定註解的組件。
特定的組件包括:

  • @Component:基於註解,標識了一個受Spring管理的組件;
  • @Resposity:標識持久層組件;
  • @Service:標識服務層(業務層)組件;
  • @Controller:標識表現層組件;

  • @Autowired默認按類型匹配注入Bean;
  • @Resource按名稱匹配注入Bean;
  • @Inject和@Autowired一樣按類型注入Bean的,只不過他沒有required屬性。

Spring通過@Autowired註解實現Bean的依賴注入
1.首先通過註解的方式創建bean

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component 
@Scope("prototype") //多態的Bean
public class Student {

}
@Scope(“prototype”)   
@Lazy(true)   
@Component(“userDao”)   
public class UserDao {   
    ……   
    // 用於設置初始化方法   
    @PostConstruct  
    public void myInit() {   

    }   

    // 用於設置銷燬方法   
    @PreDestroy  
    public void myDestroy() {   
    }   
}

2.通過@Autowire注入

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Use {

    @Autowired
    @Qualifier("car")
    private Car car;

    @Resource
    private  UserDao userDao; 
    ....
    public String toString(){
        return car.toString();
    }

}

基於java配置的形式

<context:component-scan>除了知道如何自動註冊那些使用某種構造型(stereotype)的註解所標註的Bean,它也會自動加載使用 @Configuration註解所標註的類。在上面的配置中,base-package屬性告知Spring在哪個包內查找使用@Configuration註解所標註的所有類。

<?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-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan
base-package="包名 " />
</beans>
@Configuration  
public class SpringIOConf {   
    @Scope(“prototype”)   
    @Bean(“loginUserDao”)   
    public Car getCarInstance() {   
        return new Car();   
    }   
    @Bean
    public Bus getBusInstance() {
        return new Bus();
    }
}

獲取Bean實例的方式

在 Spring IOC 容器讀取 Bean 配置創建 Bean 實例之前, 必須對它進行實例化. 只有在容器實例化後, 纔可以從 IOC 容器裏獲取 Bean 實例並使用.

Spring 提供了兩種類型的 IOC 容器實現(獲取bean).

  • BeanFactory: IOC 容器的基本實現.
  • ApplicationContext: 提供了更多的高級特性. 是 BeanFactory 的子接口.
    BeanFactory 是 Spring 框架的基礎設施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的開發者,幾乎所有的應用場合都直接使用 ApplicationContext 而非底層的 BeanFactory
    無論使用何種方式, 配置文件時相同的.

通過工廠方法(靜態工廠方法&實例工廠方法)

public static void main(String[] args) {  
       //實例化BeanFactory  
    BeanFactory factory = new BeanFactory();  
    //調用初始化方法,傳入xml路徑  
    factory.init("spring.xml");  
    //通過bean id 獲取對象  
    Car car = (CourseService) factory.getBean("car");  
    System.out.print(car);   
}  

ApplicationContext

ApplicationContext 的主要實現類:
  • ClassPathXmlApplicationContext:
    從類路徑下加載配置文件
  • FileSystemXmlApplicationContext:
    從文件系統中加載配置文件
    ConfigurableApplicationContext 擴展於 ApplicationContext,新增加兩個主要方法:refresh() 和 close(), 讓 ApplicationContext 具有啓動、刷新和關閉上下文的能力
    ApplicationContext 在初始化上下文時就實例化所有單例的 Bean。
  • WebApplicationContext 是專門爲 WEB 應用而準備的,它允許從相對於 WEB 根目錄的路徑中完成初始化工作
    這裏寫圖片描述

從 IOC 容器中獲取 Bean
調用 ApplicationContext 的 getBean() 方法
這裏寫圖片描述

依賴注入的方式

Spring 支持 3 種依賴注入的方式

  • 屬性注入
  • 構造器注入
  • 工廠方法注入(很少使用,不推薦)

屬性注入

  • 屬性注入即通過 setter 方法注入Bean 的屬性值或依賴的對象
  • 屬性注入使用 元素, 使用 name 屬性指定 Bean 的屬性名稱,value 屬性或 子節點指定屬性值
  • 屬性注入是實際應用中最常用的注入方式
<!-- 配置一個 bean -->
    <bean id="helloWorld2" class="com.spring.helloworld.HelloWorld">
        <!-- 爲屬性賦值 -->
        <!-- 通過屬性注入: 通過 setter 方法注入屬性值 -->
        <property name="user" value="Tom"></property>
    </bean>

構造器注入

  • 按索引匹配入參
<bean id="car" class="com.spring.helloworld.Car">
        <constructor-arg value="KUGA" index="0"></constructor-arg>
        <constructor-arg value="ChangAnFord" index="1"></constructor-arg>
        <constructor-arg value="250000" index="2"></constructor-arg>
    </bean>
  • 按類型匹配入參
<bean id="car" class="com.spring.helloworld.Car">
        <constructor-arg value="KUGA" type="java.util.String"></constructor-arg>
        <constructor-arg value="ChangAnFord" type="string"></constructor-arg>
        <constructor-arg value="250000" type="float"></constructor-arg>
    </bean>

注入細節講解

  • 字面值:可用字符串表示的值,可以通過 <value>元素標籤或 value 屬性進行注入。
  • 基本數據類型及其封裝類、String 等類型都可以採取字面值注入的方式
  • 若字面值中包含特殊字符,可以使用 <![CDATA[]]>把字面值包裹起來。
<!-- 通過構造器注入屬性值 -->
    <bean id="helloWorld" class="com.spring.helloworld.HelloWorld">
        <!-- 要求: 在 Bean 中必須有對應的構造器.  -->
        <constructor-arg value="Mike"></constructor-arg>
    </bean>

    <!-- 若一個 bean 有多個構造器, 如何通過構造器來爲 bean 的屬性賦值 -->
    <!-- 可以根據 index 和 value 進行更加精確的定位. (瞭解) -->
    <bean id="car" class="com.spring.helloworld.Car">
        <constructor-arg value="KUGA" index="1"></constructor-arg>
        <constructor-arg value="ChangAnFord" index="0"></constructor-arg>
        <constructor-arg value="250000" type="float"></constructor-arg>
    </bean>
    <bean id="car2" class="com.spring.helloworld.Car">
        <constructor-arg value="ChangAnMazda"></constructor-arg>
        <!-- 若字面值中包含特殊字符, 則可以使用 DCDATA 來進行賦值. (瞭解) -->
        <constructor-arg>
            <value><![CDATA[<ATARZA>]]></value>
        </constructor-arg>
        <constructor-arg value="180" type="int"></constructor-arg>
    </bean>

引用其他的Bean

  • 組成應用程序的 Bean 經常需要相互協作以完成應用程序的功能. 要使 Bean 能夠相互訪問, 就必須在 Bean 配置文件中指定對 Bean 的引用
  • 在 Bean 的配置文件中, 可以通過 <ref>元素或 ref 屬性爲 Bean 的屬性或構造器參數指定對 Bean 的引用.
  • 也可以在屬性或構造器裏包含 Bean 的聲明, 這樣的 Bean 稱爲內部 Bean
<!-- 配置 bean -->
    <bean id="dao5" class="com.spring.ref.Dao"></bean>

    <bean id="service" class="com.spring.ref.Service">
        <!-- 通過 ref 屬性值指定當前屬性指向哪一個 bean! -->
        <property name="dao" ref="dao5"></property>
    </bean>
    <bean id="action" class="com.spring.ref.Action">
        <property name="service" ref="service2"></property>
        <!-- 設置級聯屬性(瞭解) -->
        <property name="service.dao.dataSource" value="DBCP2"></property>
    </bean>

內部 Bean

  • 當 Bean 實例僅僅給一個特定的屬性使用時, 可以將其聲明爲內部 Bean. 內部 Bean 聲明直接包含在 或 元素裏, 不需要設置任何 id 或 name 屬性
  • 內部 Bean 不能使用在任何其他地方
<!-- 聲明使用內部 bean -->
    <bean id="service2" class="com.spring.ref.Service">
        <property name="dao">
            <!-- 內部 bean, 類似於匿名內部類對象. 不能被外部的 bean 來引用, 也沒有必要設置 id 屬性 -->
            <bean class="com.spring.ref.Dao">
                <property name="dataSource" value="c3p0"></property>
            </bean>
        </property>
    </bean>

注入參數詳解:null 值和級聯屬性

  • 可以使用專用的 <null/> 元素標籤爲 Bean 的字符串或其它對象類型的屬性注入 null 值
  • 和 Struts、Hiberante 等框架一樣,Spring 支持級聯屬性的配置。
<bean id="dao2" class="com.spring.ref.Dao">
        <!-- 爲 Dao 的 dataSource 屬性賦值爲 null, 若某一個 bean 的屬性值不是 null, 使用時需要爲其設置爲 null(瞭解) -->
        <property name="dataSource"><null/></property>
    </bean>

集合屬性

  • 在 Spring中可以通過一組內置的 xml 標籤(例如: <list>, <set> 或 <map>) 來配置集合屬性.
  • 配置 java.util.List 類型的屬性, 需要指定 <list> 標籤, 在標籤裏包含一些元素. 這些標籤可以通過 <value>指定簡單的常量值, 通過 <ref>指定對其他 Bean 的引用. 通過<bean>指定內置 Bean 定義. 通過 <null/>指定空元素. 甚至可以內嵌其他集合.
  • 數組的定義和 List 一樣, 都使用 <list>
  • 配置 java.util.Set 需要使用 <set>標籤, 定義元素的方法與 List 一樣.

  • Java.util.Map 通過<map>標籤定義, <map>標籤裏可以使用多個 <entry>作爲子標籤. 每個條目包含一個鍵和一個值.

  • 必須在 <key> 標籤裏定義鍵
  • 因爲鍵和值的類型沒有限制, 所以可以自由地爲它們指定 <value> ,<ref>, <bean> 或 <null> 元素.
  • 可以將 Map 的鍵和值作爲<entry> 的屬性定義: 簡單常量使用 key 和 value 來定義; Bean 引用通過 key-ref 和 value-ref 屬性定義
  • 使用 <props>定義 java.util.Properties, 該標籤使用多個 <prop> 作爲子標籤. 每個<prop>標籤必須定義 key 屬性.
<!-- 裝配集合屬性 -->
    <bean id="user" class="com.spring.helloworld.User">
        <property name="userName" value="Jack"></property>
        <property name="cars">
            <!-- 使用 list 元素來裝配集合屬性 -->
            <list>
                <ref bean="car"/>
                <ref bean="car2"/>
            </list>
        </property>
    </bean>

    <!-- 聲明集合類型的 bean -->
    <util:list id="cars">
        <ref bean="car"/>
        <ref bean="car2"/>
    </util:list>

    <bean id="user2" class="com.spring.helloworld.User">
        <property name="userName" value="Rose"></property>
        <!-- 引用外部聲明的 list -->
        <property name="cars" ref="cars"></property>
    </bean>

使用 p 命名空間

  • 爲了簡化 XML 文件的配置,越來越多的 XML 文件採用屬性而非子元素配置信息。
  • Spring 從 2.5 版本開始引入了一個新的 p 命名空間,可以通過 <bean>元素屬性的方式配置 Bean 的屬性。
  • 使用 p 命名空間後,基於 XML 的配置方式將進一步簡化
<bean id="user3" class="com.spring.helloworld.User"
        p:cars-ref="cars" p:userName="Titannic"></bean>

bean 之間的關係:

繼承

  • Spring 允許繼承 bean 的配置, 被繼承的 bean 稱爲父 bean. 繼承這個父 Bean 的 Bean 稱爲子 Bean
  • 子 Bean 從父 Bean 中繼承配置, 包括 Bean 的屬性配置
  • 子 Bean 也可以覆蓋從父 Bean 繼承過來的配置
  • 父 Bean 可以作爲配置模板, 也可以作爲 Bean 實例. 若只想把父 Bean 作爲模板, 可以設置 的abstract 屬性爲 true, 這樣 Spring 將不會實例化這個 Bean
  • 並不是 元素裏的所有屬性都會被繼承. 比如: autowire, abstract 等.
  • 也可以忽略父 Bean 的 class 屬性, 讓子 Bean 指定自己的類, 而共享相同的屬性配置. 但此時 abstract 必須設爲 true
    <bean id="user" class="com.spring.helloworld.User">
        <property name="userName" value="Jack"></property>
        <property name="cars">
            <!-- 使用 list 元素來裝配集合屬性 -->
            <list>
                <ref bean="car"/>
                <ref bean="car2"/>
            </list>
        </property>
    </bean>
<!-- bean 之間使用 parent 來完成繼承 --> 
    <bean id="user4" parent="user" p:userName="Bob"></bean>

    <bean id="user6" parent="user" p:userName="維多利亞"></bean>

依賴

  • Spring 允許用戶通過 depends-on 屬性設定 Bean 前置依賴的Bean,前置依賴的 Bean 會在本 Bean 實例化之前創建好
  • 如果前置依賴於多個 Bean,則可以通過逗號,空格或的方式配置 Bean 的名稱
<bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean>

關聯

<!--  
        在 IOC 容器中配置 bean 之間的關聯關係
    -->
    <bean id="userDao"
        class="com.spring.ref.UserDao"></bean>

    <bean id="userService"
        class="com.spring.ref.UserService">
        <property name="userDao" ref="userDao"></property>  
    </bean>

    <bean id="userAction" 
        class="com.spring.ref.UserAction">
        <property name="userService" ref="userService"></property>
    </bean>

bean 的作用域:singleton、prototype

  • 在 Spring 中, 可以在 元素的 scope 屬性裏設置 Bean 的作用域.
  • 默認情況下, Spring 只爲每個在 IOC 容器裏聲明的 Bean 創建唯一一個實例, 整個 IOC 容器範圍內都能共享該實例:所有後續的 getBean() 調用和 Bean 引用都將返回這個唯一的 Bean 實例.該作用域被稱爲 singleton, 它是所有 Bean 的默認作用域.
    這裏寫圖片描述
    <!--  
        1. 默認情況下, IOC 容器中的 bean 是單例的! 若對象是單例的, 則在創建 IOC 容器時即創建 bean 的實例, 並對 bean 的屬性進行初始化. 
        2. 可以通過 bean 的 scope 屬性來修改 bean 的作用域. 若取值爲 prototype, 則 bean 爲原型的: 每次向容器獲取實例, 得到的都是一個新的對象.
        而且, 不在創建 IOC 容器時創建 bean 的實例了. 
        3. IOC 容器中 bean 的生命週期: 
        3.1 一般地, 討論 bean 的生命週期, 是建立在 bean 是單例的基礎上的. 
        3.2 可以爲 bean 指定 init 和 destroy 方法
        3.3 還可以通過 bean 的後置處理器來更加豐富 bean 的生命週期方法(面試時.).
    -->
    <bean id="helloWorld" 
        class="com.spring.helloworld.HelloWorld" 
        scope="singleton"
        init-method="init"
        destroy-method="destroy">
        <property name="userName" value="atguigu"></property>
    </bean>

http://blog.csdn.net/z3881006/article/details/53932779

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章