Java深入講解Bean作用域與生命周期
1. Bean 的作用域
1.1 觀看案例
現(xiàn)在有一個(gè)公共 Bean
@Component
public class UserBean {
@Bean
public User user1() {
User user = new User();
user.setId(1);
user.setName("張三");
user.setAge(18);
return user;
}
}
現(xiàn)在有一個(gè)用戶1, 進(jìn)行了修改的操作
@Controller
public class UserControllerA {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
System.out.println("用戶1修改之前: " + user1);
user.setName("王五");
return user;
}
}現(xiàn)在有用戶2, 進(jìn)行讀取操作
@Controller
public class UserControllerB {
@Autowired
private User user1;
public User getUser1() {
User user = user1;
return user;
}
}打印用戶1和用戶2公共Bean的值
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserControllerA userControllerA = context.getBean("userControllerA",UserControllerA.class);
User user = userControllerA.getUser1();
System.out.println("用戶1修改之后: " + user);
UserControllerB userControllerB = context.getBean("userControllerB",UserControllerB.class);
User user1 = userControllerB.getUser1();
System.out.println("用戶2讀取到的: " + user1);
}
運(yùn)行結(jié)果

原因:
Spring 中 Bean 的作用域默認(rèn)是 singleton 單例模式. 所有人使用的都是同一個(gè)對(duì)象.
1.2 作用域的定義
之前所說的作用域, 是在程序中定義的某個(gè)變量的某個(gè)區(qū)域就叫做作用域.這里的Bean作用域不同.
Bean 的作用域指: Bean在 Spring 整個(gè)框架中的某種行為模式,
比如 singleton 單例作用域, 就表示 Bean 在整個(gè) Spring 中只有一份, 它是全局共享的, 那么當(dāng)其他人修改了這個(gè)值之后, 那么另一個(gè)人讀取到的就是被修改的值.
1.3 Bean 的 6 種作用域
Spring 容器在初始化一個(gè) Bean 的示例時(shí), 同時(shí)會(huì)指定該實(shí)例的作用域.
Spring 有 6 種作用域.
singleton: 單例作用域prototype: 原型作用域 (多例作用域)request: 請(qǐng)求作用域session: 回話作用域application: 全局作用域websocket: HTTP WebSocket 作用域
3~6 這四種是 Spring MVC 中的值.
1.4 如何設(shè)置 Bean 的作用域
@Scope 既可以用于方法注解, 也可以用于類注解
① @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)


② @Scope(“prototype”)


注意事項(xiàng):
如果是 @Bean + @Scope , 這里的@Scope 就不能寫成類注解的方式了.

2. Bean 的生命周期
2.1 Bean 的執(zhí)行流程
- 啟動(dòng) Spring 容器
- 加載 Spring 配置文件
- 加載 Spring 配置文件中的 Bean, 或根據(jù)配置文件中的組件根路徑, 進(jìn)行 Bean 對(duì)象的掃描(掃描@Controller…)
- Bean 注冊(cè)到 Spring 中
- 執(zhí)行完畢,執(zhí)行銷毀操作

2.2 Bean 生命周期
Bean 的生命周期分為 5 大部分:
實(shí)例化 Bean (為Bean分配內(nèi)存空間)
設(shè)置屬性 (Bean 進(jìn)行初始化注入)
Bean 初始化 (一系列準(zhǔn)備工作)
① 各種通知 (xxxAware)
② 執(zhí)行初始化前置方法 BeanPostProcessor
③ 執(zhí)行 @PostConstruct 初始化方法
④ 執(zhí)行 init-mehtod 初始化方法
⑤ 執(zhí)行初始化后置方法 BeanPostProcessor
使用 Bean
銷毀 Bean
- ① 執(zhí)行銷毀前方法
@PreDestory - ② 如果有接口
DisposableBean, 執(zhí)行實(shí)現(xiàn)方法 - ③ 執(zhí)行銷毀前的方法
destory-method

2.3 生命周期演示代碼
主要代碼
package com.wwzz.util;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class BeanLifeComponent implements BeanNameAware {
@Override
public void setBeanName(String s) {
System.out.println("執(zhí)行通知: BeanNameAware " + s);
}
@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í)行 @PreDestroy");
}
public void destroy() {
System.out.println("執(zhí)行 destroy");
}
}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"> <!-- 配置 Spring 掃描的根路徑(此根路徑下的所有 Spring 存對(duì)象的注解才能生效) --> <content:component-scan base-package="com.wwzz"></content:component-scan> <beans> <bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean> </beans></beans><?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">
<!-- 配置 Spring 掃描的根路徑(此根路徑下的所有 Spring 存對(duì)象的注解才能生效) -->
<content:component-scan base-package="com.wwzz"></content:component-scan>
<beans>
<bean id="beanLifeComponent" class="com.wwzz.util.BeanLifeComponent" init-method="init" destroy-method="destroy"></bean>
</beans>
</beans>
測(cè)試運(yùn)行
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
BeanLifeComponent beanLifeComponent = context.getBean("beanLifeComponent",BeanLifeComponent.class);
context.destroy();
}
查看結(jié)果

到此這篇關(guān)于Java深入講解Bean作用域與生命周期的文章就介紹到這了,更多相關(guān)Bean作用域與生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程
最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Java數(shù)據(jù)結(jié)構(gòu)通關(guān)時(shí)間復(fù)雜度和空間復(fù)雜度
對(duì)于一個(gè)算法,其時(shí)間復(fù)雜度和空間復(fù)雜度往往是相互影響的,當(dāng)追求一個(gè)較好的時(shí)間復(fù)雜度時(shí),可能會(huì)使空間復(fù)雜度的性能變差,即可能導(dǎo)致占用較多的存儲(chǔ)空間,這篇文章主要給大家介紹了關(guān)于Java時(shí)間復(fù)雜度、空間復(fù)雜度的相關(guān)資料,需要的朋友可以參考下2022-05-05
java編程隊(duì)列數(shù)據(jù)結(jié)構(gòu)代碼示例
這篇文章主要介紹了java編程隊(duì)列數(shù)據(jù)結(jié)構(gòu)代碼示例,簡(jiǎn)單介紹了隊(duì)列的相關(guān)基礎(chǔ)知識(shí),然后通過實(shí)例向大家展示其實(shí)現(xiàn)方法,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
基于spring?@Cacheable?注解的spel表達(dá)式解析執(zhí)行邏輯
這篇文章主要介紹了spring?@Cacheable?注解的spel表達(dá)式解析執(zhí)行邏輯,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
Python連接Java Socket服務(wù)端的實(shí)現(xiàn)方法
這篇文章主要介紹了Python連接Java Socket服務(wù)端的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
淺談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口
下面小編就為大家?guī)硪黄獪\談java web中常用對(duì)象對(duì)應(yīng)的實(shí)例化接口。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02

