Spring Bean--Bean的配置項、作用域、生命週期

在Spring的IOC裏,把一切配置到IOC容器裏的實體或對象都稱爲bean。
Bean配置項:
這裏寫圖片描述

  • id:在整個IOC容器中,這個bean的唯一標識
  • class:具體要實例化的類(必須)
  • scope:範圍、作用域
  • constructor arguments:構造器的參數
  • properties:屬性
  • autowiring mode:自動裝配的模式
  • lazy-initialization mode:懶加載模式
  • initialization/destruction method:初始化/銷燬的方法

從bean容器中得到某一個實例的方式:

  1. 通過id來獲取(必須配置id)
  2. 根據bean的類型來獲取(只需配置class)

Bean的作用域:
這裏寫圖片描述
注:單例singleton模式是spring bean的默認模式
例:(singleton與prototype)
BeanScope:

package com.bean;

public class BeanScope {    
    public void say(){
        System.out.println("BeanScope say:"+this.hashCode()); //通過hashcode來區分是否爲同一個實例
    }
}

spring-beanscope.xml:

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

        <!-- 設置bean的作用域爲singleton  
        <bean id="beanScope" class="com.bean.BeanScope" scope="singleton"></bean>
        -->
        <bean id="beanScope" class="com.bean.BeanScope" scope="prototype"></bean>       
 </beans>

測試TestBeanScope:

package com.test.bean;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

import com.bean.BeanScope;
import com.imooc.test.base.UnitTestBase;

@RunWith(BlockJUnit4ClassRunner.class)
public class TestBeanScope extends UnitTestBase {

    public TestBeanScope() {
        super("classpath*:spring-beanscope.xml");
    }

    @Test
    public void testSay(){
        BeanScope beanScope=super.getBean("beanScope"); //從IOC容器中獲取bean
        beanScope.say();

        BeanScope beanScope2=super.getBean("beanScope"); //從IOC容器中獲取bean
        beanScope2.say();  //若在一個IOC容器中scope設置爲singleton,則兩次輸出hashcode相同
                           //若在一個IOC容器中scope設置爲prototype,則兩次輸出hashcode不同
    }

    @Test
    public void testSay2(){ //這種情況下兩個方法執行的結果hashcode不相同是因爲每一個測試方法都會執行@before、@test、@after,雖然方法體一樣,但是是從兩個spring的IOC容器中獲取的,所以bean的hashcode不同
        BeanScope beanScope=super.getBean("beanScope"); //從IOC容器中獲取bean
        beanScope.say();

        BeanScope beanScope2=super.getBean("beanScope"); //從IOC容器中獲取bean
        beanScope2.say();  //若在一個IOC容器中scope設置爲singleton,則兩次輸出hashcode相同
    }

}

Bean的生命週期:

  1. Bean的定義:在Spring的bean的配置文件(xml文件)中爲bean定義id和class
  2. Bean的初始化:在IOC容器啓動時加載bean配置文件裏的bean,並初始化,生成bean的實例
  3. Bean的使用:在單元測試或實際開發中從bean容器中取出一個bean的實例,然後調用它的方法
  4. Bean的銷燬:在bean容器停止的時候去銷燬由當前這個bean容器創建的所有的bean的實例

初始化:兩種方式
方式一:
這裏寫圖片描述
這裏寫圖片描述
IOC容器加載這個bean,判斷是否實現了InitializingBean這個接口,然後自動調用afterPropertiesSet方法,執行初始化工作,不需要實現init-method。
方式二:
這裏寫圖片描述
當IOC容器加載這個bean並初始化的時候,就會根據init-method指定的方法去調用ExampleBean的init方法,去執行一些初始化的工作。

Bean的銷燬:兩種方式
方式一:
這裏寫圖片描述
這裏寫圖片描述
當bean銷燬的時候,也就是調用ApplicationContext的銷燬方法的時候就會調用這個bean實例的destroy方法,執行方法的內容
方式二:
這裏寫圖片描述
當bean銷燬的時候,也就是調用ApplicationContext的銷燬方法的時候就會調用這個bean實例的cleanup方法,執行一些銷燬的工作,比如釋放連接池操作。

注:以上的初始化和銷燬方法都是針對具體的某一個bean的配置,那麼配置全局默認初始化、銷燬方法:
這裏寫圖片描述
在bean的配置文件的<beans>裏配置default-init-method和default-destroy-method,那麼在這個配置文件裏的所有bean初始化的時候,也就是IOC容器在加載這些bean的時候,都會調用它的init方法,最後在IOC容器銷燬的時候都會調用默認銷燬方法destroy。
例:(bean的初始化、銷燬)
spring-lifecycle.xml配置一個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" 

        default-init-method="defautInit" default-destroy-method="defaultDestroy" >
        <!--  方式三:全局配置默認方法,若存在另外兩種方式之一,則此方式不生效-->

     <!--  方式一: 配置init-method和 destroy-method-->  
     <bean id="beanLifeCycle" class="com.lifecycle.BeanLifeCycle" init-method="start" destroy-method="stop"></bean>


     <!-- 方式二: 類必須實現InitializingBean,DisposableBean接口
     <bean id="beanLifeCycle" class="com.lifecycle.BeanLifeCycle"></bean>   
     -->
 </beans>

BeanLifeCycle.java:

package com.lifecycle;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;

public class BeanLifeCycle implements InitializingBean,DisposableBean{ //實現初始化bean和銷燬的bean的兩個接口

    //方式三:配置全局初始化和銷燬方式,在beans定義default-init-method="defautInit"等,若沒有方向defautInit也可編譯通過
    //若存在另外兩種方式之一,則此方法不生效
    public void defautInit(){
        System.out.println("Bean defautInit.");
    }

    public void defaultDestroy(){
        System.out.println("Bean defaultDestroy");
    }


    //方式二:類必須實現InitializingBean,DisposableBean接口,bean中設置id,class即可
    @Override
    public void destroy() throws Exception {
        System.out.println("Bean destroy.");        
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Bean afterPropertiesSet.");     
    }

    //方式一:bean中必須設置init-method="start" destroy-method="stop",且必須有start和stop方法,否則編譯不通過
    public void start(){
        System.out.println("Bean start.");
    }

    public void stop(){
        System.out.println("Bean stop.");
    }

}

測試類TestBeanLifecycle:

package com.test.lifecycle;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.imooc.test.base.UnitTestBase;

@RunWith(BlockJUnit4ClassRunner.class)
public class TestBeanLifecycle extends UnitTestBase {

    public TestBeanLifecycle() {
        super("classpath:spring-lifecycle.xml");
    }

    @Test
    public void test1(){
        super.getBean("beanLifeCycle"); //通過id獲取bean
    }

}

通過運行三種方式:
這裏寫圖片描述
先執行初始化,再執行銷燬。
注:同時使用三種配置方式,先執行實現接口的方法,再執行在bean中配置的init-method和destroy-method,默認的初始化和銷燬方法不生效。


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