前言
??????Spring專欄更新中,各位大佬覺得寫得不錯,支持一下,感謝了!??????
Spring_冷兮雪的博客-CSDN博客
前面我們講完了Spring中有關(guān)Bean的讀和取,我們還沒有好好去了解了解Bean對象,這篇 就是對Bean的深入學(xué)習(xí)。
一、Bean的作用域??
1、理解概念??
Singleton 單例模式是一種創(chuàng)建型設(shè)計模式,它保證一個類只有一個實例,并提供該實例的全局訪問點。
使用 Singleton 模式的主要目的是確保在一個應(yīng)用程序中,某個類的對象只有一個,這樣可以節(jié)省系統(tǒng)資源,避免對同一數(shù)據(jù)的多重處理等問題。在實現(xiàn)時,我們需要注意線程安全、延遲初始化、序列化和反射等方面的問題。
一般來說,Singleton 模式適用于那些需要頻繁訪問的對象,例如日志記錄器、數(shù)據(jù)庫連接池、線程池等等。
2、通過案例理解?Bean 作用域??
@Component
public class Users {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("Java"); // 【重點:名稱是 Java】
return user;
}
}
@Controller
public class BeanScopesController {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
System.out.println("Bean 原 Name:" + user.getName());
user.setName("悟空"); // 【重點:進(jìn)?了修改操作】
return user;
}
}
@Controller
public class BeanScopesController2 {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
return user;
}
}
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanScopesController beanScopesController = context.getBean("beanScopesController",BeanScopesController.class);
System.out.println("A 對象修改之后 " + beanScopesController.getUser1().toString());
BeanScopesController2 beanScopesController2 = context.getBean("beanScopesController2",BeanScopesController2.class);
System.out.println("B 對象讀取到的 " + beanScopesController2.getUser1().toString());
}
}
運(yùn)行結(jié)果:
?Ⅰ、原因分析??
3、Bean 的 6 種作用域(前四種為常用)??
- singleton:單例作用域
- prototype:原型作用域(多例作用域)
- request:請求作用域
- session:回話作用域
- application:全局作用域
- websocket:HTTP WebSocket 作用域
其中前兩種是 spring 核心作用域,而后 4 種是 spring mvc 中的作用域。
Ⅰ、singleton(單例模式)??
- 官方說明:(默認(rèn))將單個bean定義作用于每個Spring IoC容器的單個對象實例。
- 描述:該作用域下的Bean在IoC容器中只存在?個實例:獲取Bean(即通過 applicationContext.getBean等方法獲?。┘把b配Bean(即通過@Autowired注入)都是同一個對象。
- 場景:通常無狀態(tài)的Bean使用該作用域。無狀態(tài)表示Bean對象的屬性狀態(tài)不需要更新。
- 備注:Spring默認(rèn)選擇該作用域
Spring 框架默認(rèn)采用 Singleton 單例模式,主要是因為以下幾點原因:
-
資源消耗較少:使用單例模式可以避免頻繁創(chuàng)建對象,節(jié)約系統(tǒng)資源,提升系統(tǒng)性能。
-
對象復(fù)用:當(dāng)多個組件需要使用同一個對象時,采用單例模式可以確保這些組件使用的是同一個對象,保證了對象的一致性和正確性。
-
統(tǒng)一管理:采用單例模式可以方便地對對象進(jìn)行統(tǒng)一管理,例如設(shè)置各種屬性、初始化等操作。
-
易于擴(kuò)展:當(dāng)需要增加或修改某個類的實現(xiàn)時,只需要修改該類的單例實例即可,無需修改其他代碼。
想了解或者復(fù)習(xí)單例模式可以看這篇文章:
?面試突擊50:單例模式有幾種寫法? - 掘金 (juejin.cn)
?Ⅱ、prototype(原型模式/多例模式)??
- 官方說明:將單個bean定義限定為任意數(shù)量的對象實例。
- 描述:每次對該作用域下的Bean的請求都會創(chuàng)建新的實例:獲取Bean(即通過 applicationContext.getBean等方法獲?。┘把b配Bean(即通過@Autowired注入)都是新的對象實例。
- 場景:通常有狀態(tài)的Bean使用該作用域。有狀態(tài)表示Bean對象的屬性狀態(tài)需要更新。
Ⅲ、request(請求作用域)??
- 官方說明:將單個bean定義限定在單個HTTP請求的生命周期內(nèi)。也就是說,每個HTTP請求都有自己的bean實例,該實例是在單個bean定義的后面創(chuàng)建的。只在具有web感知的Spring ApplicationContext上下文中有效。
- 描述:每次http請求會創(chuàng)建新的Bean實例,類似于prototype。
- 場景:一次http的請求和響應(yīng)的共享Bean。
- 備注:限定SpringMVC(Spring外部項目)中使用。
Ⅳ、session(回話作用域)??
- 官方說明:將單個bean定義限定在HTTP會話的生命周期內(nèi)。只在具有web感知的Spring ApplicationContext上下文中有效。
- 描述:在一個http session中,定義?個Bean實例。
- 場景:用戶回話的共享Bean, 比如:記錄?個用戶的登陸信息。
- 備注:限定SpringMVC中使用。
Ⅴ、application(全局作用域 | 了解)??
- 官方說明:將單個bean定義限定在ServletContext的生命周期內(nèi)。僅在支持web的Spring ApplicationContext的上下文。
- 描述:在一個http servlet Context中,定義一個Bean實例。
- 場景:Web應(yīng)用的上下文信息,比如:記錄一個應(yīng)用的共享信息。
- 備注:限定SpringMVC中使用。
Ⅵ、websocket(了解)??
- 官方說明:將單個bean定義限定在WebSocket的生命周期內(nèi)。僅在一個具有web感知的Spring ApplicationContext。
- 描述:在一個HTTP WebSocket的生命周期中,定義一個Bean實例。
- 場景:WebSocket的每次會話中,保存了一個Map結(jié)構(gòu)的頭信息,將用來包裹客戶端消息頭。第一次初始化后,直到WebSocket結(jié)束都是同一個Bean。
- 備注:限定Spring WebSocket中使用。
單例作用域(singleton) VS 全局作用域(application)??
- singleton 是 Spring Core 的作用域;application 是 Spring Web 中的作用域;
- singleton 作用于 IoC 的容器,而?application 作用于 Servlet 容器。
?4、設(shè)置作用域??
設(shè)置作用域有兩種方法:
Ⅰ、直接設(shè)置值:@Scope("prototype")??
還是前面的代碼,我們給user1設(shè)置prototype作用域 (也可以設(shè)置成其他作用域)
運(yùn)行:
?Ⅱ、使用全局變量設(shè)置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)??
通過@Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)修改作用域
?我們運(yùn)行代碼也可以可以得到與 前一方法 相同的結(jié)果:
?二. Spring 執(zhí)行流程和 Bean 的生命周期??
?1、Spring 執(zhí)行流程???
- 啟動容器(啟動項目)。
- 讀取配置文件,初始化。
- a)使用 xml 直接注冊 beanb)配置 bean 根 (掃描)路徑3.將 bean 存儲到 spring 中,通過類注解進(jìn)行掃描和裝配。
- 將 bean 從 spring 讀取出來,裝配到相應(yīng)的類。
2、Bean的生命周期???
-
實例化:當(dāng)Spring容器接收到一個Bean的定義時,會根據(jù)該定義創(chuàng)建一個Bean的實例。
-
屬性賦值:創(chuàng)建Bean的實例后,Spring通過反射機(jī)制將Bean屬性設(shè)置為相應(yīng)的值。通常情況下,這些 Bean 屬性的值來自于配置文件或注解等方式。
-
初始化:在Bean實例化并設(shè)置好所有屬性之后,Spring容器將調(diào)用特定的方法對Bean進(jìn)行初始化,例如執(zhí)行自定義的初始化方法或BeanPostProcessor接口中的回調(diào)方法等。
-
使用:當(dāng)Bean初始化完成后,它可以被Spring容器使用了。在此階段,Bean可以響應(yīng)容器中的請求,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯。
-
銷毀:當(dāng)應(yīng)用程序關(guān)閉或者Spring容器銷毀時,會調(diào)用已注冊的bean的銷毀方法,以釋放資源。這個銷毀方法也可以是自定義的,需要實現(xiàn)DisposableBean接口或者添加@PreDestroy注解。
多學(xué)一招:?實例化和初始化的區(qū)別
實例化和初始化是Bean生命周期中的兩個不同階段。
實例化:指根據(jù)配置文件或注解等方式,創(chuàng)建一個對象實例的過程。在Spring容器啟動時,會根據(jù)定義的Bean定義信息創(chuàng)建相應(yīng)的Bean實例,并將其添加到容器中進(jìn)行管理。這個過程可以通過構(gòu)造函數(shù)、工廠方法或者其他方式來實現(xiàn)。
初始化:指在Bean實例化后,進(jìn)行必要的屬性設(shè)置、調(diào)用接口方法以及執(zhí)行自定義初始化方法等操作,使得Bean達(dá)到可以使用的狀態(tài)。在Spring容器創(chuàng)建了Bean實例之后,會根據(jù)配置信息和需要執(zhí)行一定的初始化操作,例如調(diào)用BeanPostProcessor接口中的回調(diào)方法、執(zhí)行自定義的初始化方法等等。
總之,Bean的實例化和初始化是在Spring容器中管理Bean的重要環(huán)節(jié),它們各自都有著不同的作用和實現(xiàn)方式。文章來源:http://www.zghlxwxcb.cn/news/detail-479664.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-479664.html
到了這里,關(guān)于【Spring】——Spring生命周期的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!