Spring--Bean對象詳解

在Spring中,對象無需自己查找或創建與其所關聯的其他對象(解耦合)。
Spring容器負責創建應用程序中的bean並通過DI來協調Java對象之間的關係。
創建應用對象之間協作關係的行爲通常稱爲裝配(wiring),這也是依賴注入(DI)的本質。

總而言之,bean對象就是應用程序中的Java對象,Spring容器創建並封裝這些Java對象爲容器中的bean對象,在需要時自動注入到變量中,賦予對應Java對象的實例。

Spring配置bean的三種方式

  • 1.在XML中進行顯式配置。
  • 2.在Java中進行顯式配置。
  • 3.隱式的bean發現機制和自動裝配。

本文以XML中的顯式配置介紹bean對象的創建方式、作用範圍、生命週期等。

創建bean的方式

1 通過構造函數創建Java對象對應的bean
1.1 無參構造函數(默認構造函數)
<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" ></bean>

如上,通過AccountServiceImpl的默認構造函數創建了AccountServiceImpl實例化的bean對象。在Java代碼中定義的 AccountServiceImpl 類或其父類對象變量,會根據變量名對應bean的id自動注入。

1.1 帶參構造函數
<bean id="accountDao" class="com.simple.Dao.impl.AccountDaoImpl" ></bean>

<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl" >
	<constructor-arg ref="accountDao"></constructor-arg>
	<constructor-arg value="#{T(其他各種類型,如string等等)}"></constructor-arg>
</bean>        

accountDao代表在AccountServiceImpl類構造函數中需要注入的Java對象,ref 屬性的值爲該Java對象對應的bean的id值;#{T}是Spring中的EL表達式,T表示構造函數中帶有的其他類型參數(基本類型,如String等等)。

2 使用普通工廠中的方法創建對象,並存入指定的bean

使用某個工廠類中的方法創建Java對象,並存入spring容器。

工廠類:

public class InitFactory {
    public IAccountService getAccountService(){
        return new AccountServiceImpl();
    }
}

XML配置:

<bean id="initFactory" class="com.simple.factory.InitFactory"></bean>
<bean id="accountService" factory-bean="initFactory" factory-method="getAccountService"></bean>
3 使用工廠中的靜態方法創建對象,並存入指定的bean

使用某個類中的靜態方法創建Java對象,並存入spring容器。由於使用的是工廠中的靜態方法,所以不需要實例化工廠。

工廠類:

public class staticFactory {
    public static IAccountService getAccountService(){
        return new AccountServiceImpl();
    }
}

XML配置:

<bean id="accountService" class="com.simple.factory.staticFactory" factory-method="getAccountService"></bean>

上述三種創建bean的方式中,一般使用第1種方法通過構造函數創建bean。

bean的作用範圍

bean的作用範圍由 bean 標籤的 scope 屬性來指定。其屬性值包括:

屬性值 說明
singleton 默認值,指定bean爲單例的
prototype 指定bean爲多例的
request web項目中,作用於request域
session web項目中,作用於session域
global-session web項目中,作用於集羣環境的session域;若不是集羣環境,則相當於session

一般常用的是 singleton ,即單例的。

單例的bean表示Spring容器中該bean只有一個對應的實例化Java對象;多例的bean表示Spring容器中該bean可以有對應類多個實例化Java對象(可通過其存儲地址區分)。

bean對象的生命週期

1 單例bean
  1. 默認情況下,Spring讀取XML配置文件創建Spring容器時bean對象就會被創建
  2. 在創建對象時,先執行對象的構造方法,然後調用bean標籤的 init-method="..."屬性值中指定的方法
  3. 在Spring容器銷燬時,單例bean隨之消亡。bean消亡即對象被銷燬時,會調用bean標籤的 destroy-method="..."屬性值中指定的方法
  4. 可以設置bean標籤的 lazy-init="true" 使該對象在第一次被訪問時才創建

XML配置:創建單例bean,指定init-method="..."destroy-method="..."屬性

<bean id="accountService" class="com.simple.service.impl.AccountServiceImpl"
	scope="singleton" init-method="init" destroy-method="destory">
</bean>

AccountServiceImpl 類:

public class AccountServiceImpl implements IAccountService {

    //默認無參構造器
    public AccountServiceImpl() {
        System.out.println("對象已創建!");
    }

    public void saveAccount() {
        System.out.println("Service中的saveAccount方法執行了!!");
    }

    //初始時執行方法
    public void init(){
        System.out.println("對象初始化了!!!");
    }

    //銷燬時執行方法
    public void destory(){
        System.out.println("對象銷燬了!!!");
    }
}

測試單例bean的生命週期:

public class Client {

    public static void main(String[] args) {
        //1.獲取Spring核心容器對象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");   //bean.xml放在根目錄下,所有可以直接寫文件名
        //2.根據id獲取bean對象
        //可以使用強制類型轉換
        //IAccountService as = (IAccountService) ac.getBean("accountService");
        //也可以指定對象類型
        IAccountService as = ac.getBean("accountService",IAccountService.class);
        //查看創建的as對象
        System.out.println(as);

		//執行as對象的方法
        as.saveAccount();

        //手動銷燬Spring容器,查看as對象消亡過程
        ac.close();
        System.out.println("結束!");
    }
}

結果如下:
在這裏插入圖片描述

2 多例bean
  1. Spring讀取XML配置文件創建Spring容器時,不會立刻創建多例bean對應的對象
  2. 在每一次訪問這個多例bean對應的對象的時,spring容器都會創建該對象,並且調用init-method=".."屬性值中所指定的方法
  3. Spring容器銷燬時,多例bean對應創建的對象也不會消亡。因爲是多例的(該類型的對象可以有多個),所以在Spring容器創建該對象並將它賦予給Java變量後,該對象就由Java的進行管理,銷燬該對象也由垃圾回收機制進行回收。spring容器一旦把這個對象交給Java之後,就不再管理這個對象了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章