文章目錄
- 1、FactoryBean(工廠Bean)
- 2、Bean的作用域
- 3、Bean的生命周期
- 3.1、bean生命周期(沒有bean的后置處理器)
- 3.2、bean的生命周期:添加了bean的后置處理器
- 4、Xml的自動裝配
1、FactoryBean(工廠Bean)
Spring中有兩種型別的bean,一種是普通Bean,另一種是工廠Bean
- 普通Bean:在組態檔中定義的bean型別就是回傳型別
- 工廠Bean:在組態檔中定義bean型別可以與回傳型別不一樣
1、普通Bean
Service service = context.getBean("service", Service.class);
xml檔案中class屬性中最后的類名Service就是回傳型別,這就是一個普通bean
<bean id="service" class="Test_bean.Service">
<property name="list" ref="list"></property>
</bean>
2、工廠Bean
- 第一步 創建類,讓這個類作為工廠Bean,實作介面FactoryBean,并重寫其中的方法
- getObject( ):該方法回傳的是Mybean“生產”的物件
- getObjectType( ):該方法回傳getObject( )方法所回傳的物件的型別
- isSingleton( ):該方法回傳的是getObject( )“生產”的物件是不是單例,如果是則回傳true,不是則回傳false
public class MyBean implements FactoryBean {
//在這里我定義了它生產的物件是String型別
@Override
public String getObject() throws Exception {
return "service";
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
- 通過Spring組態檔配置屬性
<bean id="mybean" class="FactoryBean.MyBean"></bean>
- 創建測驗類,進行測驗
public class Springtest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
String string = context.getBean("mybean", String.class);
System.out.println(string);
}
}
- 測驗結果
service
2、Bean的作用域
bean具有五大作用域,在bean配置標簽中,利用scope屬性來設定其作用域,
- singleton:在Spring IOC容器中僅存在一個Bean實體,Bean以單例方式存在,如果不設定其作用域,此作用域為默認值
- prototype:每次從容器中呼叫Bean時,都會回傳一個新的實體,即每次呼叫getBean( )時,相當于執行一次new物件的程序,
- request:每次HTTP請求都會創建一個新的Bean,該作用域僅適用于WebApplicationContext
- session:同一個HTTP Session共享一個Bean,不同Session使用不同Bean,僅適用于WebApplicationContext環境
- globalSession:一般用于Portlet應用環境,該作用域僅適用于WebApplocationContext環境
五種作用域,request、session和globalSession只在web應用中使用,因此在此我只對singleton和prototype做出解釋,
1、singleton屬性值:單實體(代碼解釋)
- 創建Service類
public class Service {
}
- Spring組態檔中,設定scope屬性值為singleton
<bean id="mybean" class="Test_bean.Service" scope="singleton"></bean>
- 創建測驗類,測驗代碼
public class Springtest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Service service = context.getBean("mybean", Service.class);
Service service1 =context.getBean("mybean",Service.class);
System.out.println(service);
System.out.println(service1);
}
}
- 測驗結果
//同一實體,地址相同
Test_bean.Service@1189dd52
Test_bean.Service@1189dd52
2、prototype屬性值:多實體(代碼解釋)
- 創建Service類(同上)
- Spring組態檔中,設定scope屬性值為prototype
<bean id="mybean" class="Test_bean.Service" scope="prototype"></bean>
- 創建測驗類,進行測驗(同上)
- 測驗結果
Test_bean.Service@2d7275fc
Test_bean.Service@399f45b1
3、Bean的生命周期
概念:從物件創建到物件銷毀的程序
3.1、bean生命周期(沒有bean的后置處理器)
- 通過構造器創建bean實體(無引數構造)
- 為bean的屬性設定值和對其他bean參考(呼叫set方法)
- 呼叫bean的初始化的方法(需要進行配置初始化的方法)
- bean可以使用了(物件獲取到了)
- 當容器關閉時候,呼叫bean的銷毀的方法(需要進行配置銷毀的方法)
說明:在配置bean.xml檔案時,通過init-method和destroy-method屬性為bean指定初始化和銷毀的方法
代碼演示:
- 創建Service類,創建初始化,set,init-method,destroy-method方法
public class Service {
private String name;
public Service(){
System.out.println("第一步:執行無引數構造方法創建bean實體");
}
public void setName(String name) {
this.name = name;
System.out.println("第二步:呼叫setter方法為屬性賦值");
}
public void initMethod(){
System.out.println("第三步:執行init-method初始化方法");
}
public void destroyMethod(){
System.out.println("第五步:執行destroy-method銷毀方法");
}
}
- 在Spring組態檔中,指定init-method和destroy-method方法
<bean id="service" class="Test_bean.Service" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="offer"></property>
</bean>
- 創建測驗類,進行測驗
注意:需要關閉IOC容器才會執行destroy-method方法,并且介面類需要上升到ConfigurableApplicationContext才會提供close( )方法
public class Springtest {
@Test
public void test(){
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Service service = context.getBean("service", Service.class);
System.out.println("第四步:使用物件:"+service);
context.close();
}
}
- 測驗結果
第一步:執行無引數構造方法創建bean實體
第二步:呼叫setter方法為屬性賦值
第三步:執行init-method初始化方法
第四步:使用物件:Test_bean.Service@40a4337a
第五步:執行destroy-method銷毀方法
3.2、bean的生命周期:添加了bean的后置處理器
1、bean的后置管理器
- bean的后置處理器允許在呼叫初始化方法前后對bean進行額外的處理
- bean的后置處理器對IOC容器里的所有bean實體逐一處理,而非單一實體,
- bean后置處理器時需要實作介面:org.springframework.beans.factory.config.BeanPostProcessor,在初始化方法被呼叫前后,Spring將把每個bean實體分別傳遞給上述介面的以下兩個方法:
- postProcessBeforeInitialization(Object, String)
- postProcessAfterInitialization(Object, String)
2、添加bean的后置處理器后bean的生命周期
- 通過構造器創建bean實體(無引數構造)
- 為bean的屬性設定值和對其他bean參考(呼叫set方法)
- 將bean實體傳遞給bean后置處理器的postProcessBeforeInitialization()方法
- 呼叫bean的初始化的方法(需要進行配置初始化的方法)
- 將bean實體傳遞給bean后置處理器的postProcessBeforeInitialization()方法
- bean可以使用了(物件獲取到了)
- 當容器關閉時候,呼叫bean的銷毀的方法(需要進行配置銷毀的方法)
3、 代碼演示:
- 創建MyBean類,實作BeanPostProcessor介面,重寫postProcessBeforeInitialization和postProcessBeforeInitialization方法
public class MyBean implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第三步:執行postProcessBeforeInitialization方法");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("第五步:執行postProcessAfterInitialization方法");
return null;
}
}
- 創建Service類
public class Service {
private String name;
public Service(){
System.out.println("第一步:執行無引數構造方法創建bean實體");
}
public void setName(String name) {
this.name = name;
System.out.println("第二步:呼叫setter方法為屬性賦值");
}
public void initMethod(){
System.out.println("第四步:執行init-method初始化方法");
}
public void destroyMethod(){
System.out.println("第七步:執行destroy-method銷毀方法");
}
}
- 在Spring組態檔中實體化自定義的MyBean后置處理器
<bean id="service" class="Test_bean.Service" init-method="initMethod" destroy-method="destroyMethod">
<property name="name" value="offer"></property>
</bean>
<bean id="mybean" class="FactoryBean.MyBean"></bean>
- 創建測驗類
public class Springtest {
@Test
public void test(){
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Service service = context.getBean("service", Service.class);
System.out.println("第六步:使用物件:"+service);
context.close();
}
}
- 測驗結果
第一步:執行無引數構造方法創建bean實體
第二步:呼叫setter方法為屬性賦值
第三步:執行postProcessBeforeInitialization方法
第四步:執行init-method初始化方法
第五步:執行postProcessAfterInitialization方法
第六步:使用物件:Test_bean.Service@4c402120
第七步:執行destroy-method銷毀方法
4、Xml的自動裝配
1、概念:根據指定的裝配規則,不需要明確指定,Spring自動將匹配的屬性值注入bean中
2、在Spring組態檔中,通過autowire標簽設定自動裝配的方式:
- byType:將型別匹配的bean作為屬性注入到另一個bean中,若IOC容器中有多個與目標bean型別一致的bean,Spring將無法判定那個bean最合適該屬性,所以不能執行自動裝配
- byName:必須將目標bean的名稱和屬性名設定的完全相同
- constructor:當bean中存在多個構造器時,此種自動裝配方式將會很復雜
3、代碼演示:
- 創建兩個類Service和Dao類,在Service類中以Dao型別作為屬性
public class Dao {
private String name;
public void setName(String name) {
this.name = name;
}
public void print(){
System.out.println("my name is "+name);
}
}
public class Service {
private Dao dao;
public void setDao(Dao dao) {
this.dao = dao;
}
public void print(){
dao.print();
}
}
- 在Spring組態檔中設定自動裝配的方式
<bean id="service" class="Test_bean.Service" autowire="byName"></bean>
<!--byName:需要下面的bean的id值與Service類中的屬性值相同-->
<bean id="dao" class="Test_bean.Dao">
<property name="name" value="offer"></property>
</bean>
<bean id="service" class="Test_bean.Service" autowire="byType"></bean>
<bean id="dao" class="Test_bean.Dao">
<property name="name" value="offer"></property>
</bean>
<!--byType需要注意的是,如果有多個Dao類的bean,Spring就無法判斷注入那個bean-->
<!--<bean id="dao1" class="Test_bean.Dao">-->
<!--<property name="name" value="offer"></property>-->
<!--</bean>-->
- 創建測驗類,進行測驗
public class Springtest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
Service service = context.getBean("service", Service.class);
service.print();
}
}
- 測驗結果:
my name is offer
??????????????????????????????????????????????????
若對Spring基礎知識感興趣的可以關注一下博主,我會持續更新Spring基礎知識(一邊學習一邊記錄),一起進步,有錯誤的地方也可以在評論區指出來喔,謝謝大家啦!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/271566.html
標籤:java
