Java之Spring Bean 作用域和生命周期
Bean 作用域和生命周期
Bean 作用域
Bean 的作用域是指 Bean 在 Spring 整個(gè)框架中的某種行為模式.
比如 singleton 單例作用域, 就表示 Bean 在整個(gè) Spring 中只有一份, 它是全局共享的, 那么當(dāng)其他人修改了這個(gè)值之后, 那么另一個(gè)人讀取到的就是被修改的值.
Bean 作用域分類
- singleton: 單例作用域 (默認(rèn)作用域)
- prototype: 原型作用域 (多例作用域)
- request: 請(qǐng)求作用域
- session: 回話作用域
- application: 全局作用域
- websocket: HTTP
# 注意 # 后 4 種狀態(tài)是 Spring MVC 中的值,在普通的 Spring 項(xiàng)?中只有前兩種.
singleton
Bean 默認(rèn)情況下是單例狀態(tài)(singleton),也就是所有?的使?的都是同?個(gè)對(duì)象,之前我們學(xué)單例模式的時(shí)候都知道,使用單例可以很大程度上提高性能,所以在 Spring 中Bean 的作用域默認(rèn)也是 singleton 單例模式。
- 描述:該作用域下的 Bean 在 IoC 容器中只存在?個(gè)實(shí)例:獲取 Bean(即通過 applicationContext.getBean 等方法獲?。┘把b配 Bean(即通過 @Autowired 注入)都是同?個(gè)對(duì)象.
- 場(chǎng)景:通常無狀態(tài)的 Bean 使用該作用域. (無狀態(tài)表示 Bean 對(duì)象的屬性狀態(tài)不需要更新)
prototype
- 描述:每次對(duì)該作用域下的 Bean 的請(qǐng)求都會(huì)創(chuàng)建新的實(shí)例:獲取 Bean(即通過 applicationContext.getBean 等方法獲取)及裝配 Bean(即通過 @Autowired 注入)都是新的對(duì)象實(shí)例。
- 場(chǎng)景:通常有狀態(tài)的Bean使?該作用域.
request
- 描述:每次 http 請(qǐng)求會(huì)創(chuàng)建新的 Bean 實(shí)例,類似于prototype
- 場(chǎng)景:?次 http 的請(qǐng)求和響應(yīng)的共享 Bean
- 備注:限定 SpringMVC 中使?
session
- 描述:在?個(gè) http session 中,定義?個(gè) Bean 實(shí)例
- 場(chǎng)景:?戶回話的共享 Bean , 比如: 記錄?個(gè)?戶的登陸信息
- 備注:限定 SpringMVC 中使?
application (了解)
- 描述:在?個(gè) http servlet Context 中,定義?個(gè) Bean 實(shí)例
- 場(chǎng)景:Web 應(yīng)?的上下文信息, 比如:記錄?個(gè)應(yīng)用的共享信息
- 備注:限定 SpringMVC 中使?
websocket (了解)
- 描述:在?個(gè) HTTP WebSocket 的?命周期中,定義?個(gè) Bean 實(shí)例
- 場(chǎng)景:WebSocket 的每次會(huì)話中,保存了?個(gè) Map 結(jié)構(gòu)的頭信息,將?來包裹客戶端消息頭。第?次初始化后,直到 WebSocket 結(jié)束都是同?個(gè) Bean。
- 備注:限定 Spring WebSocket 中使?
單例作用域 (singleton) VS 全局作用域 (application)
- singleton 是 Spring Core 的作用域, application 是 Spring Web 中的作用域.
- singleton 作用于 IoC 的容器, application 作用于 Servlet 容器
Bean 作用域的設(shè)置
@Scope 標(biāo)簽既可以修飾?法也可以修飾類,@Scope 有兩種設(shè)置?式
使?枚舉設(shè)置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component public class UserBeans { @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Bean public User user1() { User user = new User(); user.setId(1); user.setName("Gujiu"); user.setPassword("123456"); return user; } }
直接設(shè)置值: @Scope("prototype")
@Component public class UserBeans { @Scope("prototype") @Bean public User user1() { User user = new User(); user.setId(1); user.setName("Gujiu"); user.setPassword("123456"); return user; } }
Spring 執(zhí)行流程
- 啟動(dòng)容器 (啟動(dòng)項(xiàng)目)
- 讀取配置文件 (初始化)
- 使用
xml
直接注冊(cè) Bean - 配置
Bean
根 (掃描) 路徑
- 使用
- 將 Bean 存儲(chǔ)到
Spring
中: 通過類注解進(jìn)行掃描和裝配 - 將
Bean
裝配到需要的類中 (取操作)
Bean 生命周期
所謂的?命周期指的是?個(gè)對(duì)象從誕?到銷毀的整個(gè)?命過程,我們把這個(gè)過程就叫做?個(gè)對(duì)象的?命周期。
Bean 的生命周期:
- 實(shí)例化 Bean (對(duì)應(yīng) JVM 中的 “加載”, 從無到有, 將字節(jié)碼轉(zhuǎn)換成內(nèi)存中的對(duì)象, 只是分配了內(nèi)存) [買了一套毛坯房]
- 設(shè)置屬性 (Bean 的注入和裝配) [購(gòu)買裝修材料 (引入外部資源)]
- Bean 初始化 [房子裝修]
- 實(shí)現(xiàn)了各種 Aware 通知的方法,如 BeanNameAware、BeanFactoryAware、ApplicationContextAware 的接口方法 [打電話給各個(gè)裝修的師傅]
- 執(zhí)行 BeanPostProcessor 初始化前置方法 [師傅勘察環(huán)境, 指定裝修方案 (前置工作)]
- 執(zhí)行 @PostConstruct 初始化方法,依賴注入操作之后被執(zhí)行 [兩類裝修師傅進(jìn)行裝修]
- 執(zhí)行自己指定的 init-method 方法 (如果有指定的話) [兩類裝修師傅進(jìn)行裝修]
- 執(zhí)行 BeanPostProcessor 初始化后置方法 [裝修之后的清理工作]
- 使用 Bean [房子可以入住使用了]
- 銷毀 Bean [賣掉房子]
生命周期演示
BeanLifeComponent 類:
//@Component public class BeanLifeComponent implements BeanNameAware { @Override public void setBeanName(String s) { System.out.println("執(zhí)行了通知"); } @PostConstruct public void postConstruct() { System.out.println("執(zhí)行了 @PostConstruct"); } public void init() { System.out.println("執(zhí)行了 init-method"); } @PreDestroy public void preDestroy() { System.out.println("執(zhí)行了銷毀方法"); } }
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" xmlns:content="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean id="myComponent" class="com.demo.component.BeanLifeComponent" init-method="init" ></bean> </beans>
調(diào)用類:
public class App2 { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml"); BeanLifeComponent beanLifeComponent = applicationContext.getBean("myComponent", BeanLifeComponent.class); System.out.println("使用Bean"); applicationContext.destroy(); } }
運(yùn)行結(jié)果展示:
到此這篇關(guān)于Java之Spring Bean 作用域和生命周期的文章就介紹到這了,更多相關(guān)Spring Bean作用域和生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot之解決多個(gè)定時(shí)任務(wù)阻塞的問題
這篇文章主要介紹了SpringBoot之解決多個(gè)定時(shí)任務(wù)阻塞的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04mybatis-plus主鍵id生成、字段自動(dòng)填充的實(shí)現(xiàn)代碼
這篇文章主要介紹了mybatis-plus主鍵id生成、字段自動(dòng)填充的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12Java對(duì)象創(chuàng)建的幾種方式總結(jié)
本文詳細(xì)介紹了Java中創(chuàng)建對(duì)象的五種方法,包括使用new關(guān)鍵字、Class的newInstance()方法、Constructor的newInstance()方法、克隆以及反序列化,同時(shí)討論了這些方式是否調(diào)用了構(gòu)造器以及創(chuàng)建對(duì)象的條件,文章還提供了示例代碼進(jìn)行演示,需要的朋友可以參考下2025-02-02Java經(jīng)典算法匯總之順序查找(Sequential Search)
Java查找算法之順序查找說明:順序查找適合于存儲(chǔ)結(jié)構(gòu)為順序存儲(chǔ)或鏈接存儲(chǔ)的線性表。 下面我們來詳細(xì)說明下2016-04-04