前言
在之前的學習中我們知道,容器是一個空間的概念,一般理解為可盛放物體的地方。在Spring容器通常理解為BeanFactory或者ApplicationContext。我們知道spring的IOC容器能夠幫我們創建對象,對象交給spring管理之后我們就不用手動去new對象。
那么Spring是如何管理Bean的呢?
文章目錄
- 前言
- 一、概念
- 二、創建Bean對象的三種方式
- 2.1、使用默認構造函數創建方式
- 2.1.1、定義Bean
- 2.1.2、主配置文件中配置bean
- 2.1.3、測試Bean
- 2.1.4、注意點
- 2.2、使用工廠中的實例方法創建方式
- 2.2.1、定義工廠
- 2.2.2、定義Bean
- 2.2.3、主配置文件中配置Bean
- 2.2.4、測試
- 2.3、使用工廠中的靜態方法創建方式
- 2.3.1、定義工廠
- 2.3.2、定義Bean
- 2.3.3、主配置文件中配置Bean
- 2.3.4、測試
- 三、Bean對象的作用域
- 3.1、說明
- 3.2、作用域類型
- 3.3、注意細節
- 3.4、如何修改Bean的作用域
- 3.5、測試
- 3.5.1、測試singleton單例
- 3.5.2、測試prototype多例
- 四、Bean對象的生命周期
- 4.1、單例對象
- 4.1.1、說明
- 4.1.2、測試
- 4.1.2.1、定義Bean
- 4.1.2.2、主配置文件中配置Bean
- 4.1.2.3、測試
- 4.1.2.4、測試結果
- 4.2、多例對象
- 4.2.1、說明
- 4.2.2、測試
- 4.2.2.1、定義Bean
- 4.2.2.2、主配置文件中配置Bean
- 4.2.2.3、測試1
- 4.2.2.4、測試2
- 五、總結
一、概念
簡而言之,Spring bean是Spring框架在運行時管理的對象。Spring bean是任何Spring應用程序的基本構建塊。你編寫的大多數應用程序邏輯代碼都將放在Spring bean中。
Spring bean的管理包括:
- 創建一個對象
- 提供依賴項(例如其他bean,配置屬性)
- 攔截對象方法調用以提供額外的框架功能
- 銷毀一個對象
Spring bean是框架的基本概念。作為Spring的用戶,你應該對這個核心抽象有深刻的理解。
二、創建Bean對象的三種方式
2.1、使用默認構造函數創建方式
2.1.1、定義Bean
public class UserServiceImpl {}
2.1.2、主配置文件中配置bean
<!-- 方式一:使用默認構造函數方式創建Bean -->
<beans><bean id="userService" class="cn.bdqn.UserServiceImpl"></bean>
</beans>
2.1.3、測試Bean
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");// 2、從容器中根據id獲取對象(bean)UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");// 3、打印beanSystem.out.println(userService);
}
2.1.4、注意點
此種方式采用的就是通過默認構造函數的方式創建Bean,假設我們給UserServiceImpl添加了一個帶參的構造方法,則運行會報錯,原因在于當我們為某個類自定義構造方法的時候,Java編譯器便不會為該類提供默認的不帶參數的構造方法了。
2.2、使用工廠中的實例方法創建方式
2.2.1、定義工廠
// UserService的工廠,作用是創建UserServiceBean對象
public class UserServiceImplFactory {public UserServiceImpl createUserService(){return new UserServiceImpl();}
}
2.2.2、定義Bean
public class UserServiceImpl {}
2.2.3、主配置文件中配置Bean
<beans><!-- 方式二:使用工廠中提供的實例方法創建Bean --><!-- 第一步:把該工廠定義出來 --><bean id="userServiceFactory" class="cn.bdqn.UserServiceImplFactory"/><!-- 第二步:定義Bean(通過userServiceFactory中提供的實例方法)--><bean id="userService" factory-bean="userServiceFactory" factory-method="createUserService"/>
</beans>
2.2.4、測試
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");// 2、從容器中根據id獲取對象(bean)UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");// 3、打印beanSystem.out.println(userService);
}
2.3、使用工廠中的靜態方法創建方式
2.3.1、定義工廠
// UserService的工廠,作用是創建UserServiceBean對象
public class UserServiceImplFactory {public static UserServiceImpl createUserService(){return new UserServiceImpl();}
}
2.3.2、定義Bean
public class UserServiceImpl {}
2.3.3、主配置文件中配置Bean
<beans><!-- 方式三:使用工廠中提供的靜態方法創建Bean --><!-- 定義Bean(通過工廠類的靜態方法創建) --><bean id="userService" class="cn.bdqn.UserServiceImplFactory" factory-method="createUserService"></bean>
</beans>
2.3.4、測試
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");// 2、從容器中根據id獲取對象(bean)UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");// 3、打印beanSystem.out.println(userService);
}
三、Bean對象的作用域
3.1、說明
? Spring對Bean的默認的作用域(作用范圍)是singleton【單例】
3.2、作用域類型
-
singleton:單例的(默認值),只會new一次。
-
prototype:多例的,用到一次就會new一次。
-
request:作用于web應用的請求范圍,Spring創建這個類之后,將這個類存到request范圍內。
-
session:應用于web項目的會話范圍,Spring創建這個類之后,將這個類存到session范圍內。
-
global-session:作用于集群環境的會話范圍(全局會話范圍),當不是集群環境時,它就是session。
3.3、注意細節
實際開發中用得最多的就是singleton和prototype,在整合struts2的時候使用prototype,在整合SpringMVC的時候使用singleton。
3.4、如何修改Bean的作用域
bean標簽的scope屬性,作用:指定bean的作用范圍。
3.5、測試
3.5.1、測試singleton單例
public class UserServiceImpl {}
<beans><bean id="userService" class="cn.bdqn.UserServiceImpl" />
</beans>
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");// 2、從容器中根據id獲取對象(bean)UserServiceImpl userService1 = (UserServiceImpl) ac.getBean("userService");UserServiceImpl userService2 = (UserServiceImpl) ac.getBean("userService");// 3、打印beanSystem.out.println(userService1 == userService2); // true
}
3.5.2、測試prototype多例
public class UserServiceImpl {}
<bean id="userService" class="cn.bdqn.UserServiceImpl" scope="prototype"/>
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");// 2、從容器中根據id獲取對象(bean)UserServiceImpl userService1 = (UserServiceImpl) ac.getBean("userService");UserServiceImpl userService2 = (UserServiceImpl) ac.getBean("userService");// 3、打印beanSystem.out.println(userService1 == userService2); // false
}
四、Bean對象的生命周期
4.1、單例對象
4.1.1、說明
出生:當容器創建時對象出生
活著:只要容器還在,對象一直活著
死亡:容器銷毀,對象消亡
4.1.2、測試
4.1.2.1、定義Bean
public class UserServiceImpl {public UserServiceImpl(){System.out.println("對象的構造方法執行了");}public void init(){System.out.println("對象初始化了");}public void destroy(){System.out.println("對象銷毀了"); }
}
4.1.2.2、主配置文件中配置Bean
<beans><bean id="userService" class="cn.bdqn.UserServiceImpl"scope="singleton" init-method="init" destroy-method="destroy"/>
</beans>
4.1.2.3、測試
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");ac.close();
}
// 結果:對于單例對象來說,只要容器創建了,那么對象就創建了。類似于立即加載。
4.1.2.4、測試結果
對象的構造方法執行了
對象初始化了
對象銷毀了
總結:單例對象的生命周期和容器相同
4.2、多例對象
4.2.1、說明
出生:當我們使用對象時spring框架為我們創建
活著:對象只要是在使用過程中就一直活著。
死亡:當對象長時間不用,且沒有別的對象引用時,由Java的垃圾回收器回收
4.2.2、測試
4.2.2.1、定義Bean
public class UserServiceImpl {public UserServiceImpl(){System.out.println("對象的構造方法執行了");}public void init(){System.out.println("對象初始化了");}public void destroy(){System.out.println("對象銷毀了"); }
}
4.2.2.2、主配置文件中配置Bean
<beans><bean id="userService" class="cn.bdqn.UserServiceImpl"scope="prototype" init-method="init" destroy-method="destroy"/>
</beans>
4.2.2.3、測試1
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");ac.close();
}
// 結果:什么都不輸出,說明容器啟動的時候,對于多例對象來說并不會創建
4.2.2.4、測試2
@Test
public void testUserService() throws Exception{// 1、讀取主配置文件信息,獲取核心容器對象ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");UserServiceImpl userService = (UserServiceImpl) ac.getBean("userService");System.out.println(userService);ac.close();
}
/**結果:對象的構造方法執行了對象初始化了說明:對于多例對象來說,只有等到真正使用到該對象的時候才會創建。類似于懶加載。
**/
? 對于多例的Bean,Spring框架是不負責管理的
五、總結
以上就是本篇文章的全部內容了,如果對你有幫助的話,可以點個免費的關注,如果能在下方三連一下就更好啦,你的支持就是我更新的動力!