在Spring的IOC裏,把一切配置到IOC容器裏的實體或對象都稱爲bean。
Bean配置項:
- id:在整個IOC容器中,這個bean的唯一標識
- class:具體要實例化的類(必須)
- scope:範圍、作用域
- constructor arguments:構造器的參數
- properties:屬性
- autowiring mode:自動裝配的模式
- lazy-initialization mode:懶加載模式
- initialization/destruction method:初始化/銷燬的方法
從bean容器中得到某一個實例的方式:
- 通過id來獲取(必須配置id)
- 根據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的生命週期:
- Bean的定義:在Spring的bean的配置文件(xml文件)中爲bean定義id和class
- Bean的初始化:在IOC容器啓動時加載bean配置文件裏的bean,並初始化,生成bean的實例
- Bean的使用:在單元測試或實際開發中從bean容器中取出一個bean的實例,然後調用它的方法
- 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,默認的初始化和銷燬方法不生效。