最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring?Bean的作用域具體實(shí)現(xiàn)(單例、多例、請求、會(huì)話、Application)

 更新時(shí)間:2025年08月06日 10:52:02   作者:椰椰椰耶  
文章講解了Spring?IoC/?DI中Bean作用域的管理方式,涵蓋單例(singleton)、原型(prototype)及Web環(huán)境的request、session、application作用域,通過注解和配置區(qū)分不同作用域的實(shí)例創(chuàng)建規(guī)則,并通過測試驗(yàn)證其生命周期與共享特性,感興趣的朋友一起看看吧

概念

Spring Ioc&DI 戒斷,我們學(xué)習(xí)了 Spring 是如何幫助我們管理對象的

  1. 通過 @Controller,@Service@Repository,@Component,@Configuration,@Bean 來聲明 Bean 對象
  2. 通過 ApplicationContext 或者 BeanFactory 來獲取對象
  3. 通過 @Autowired,Setter 方法或者構(gòu)造方法等來為應(yīng)用程序注入所依賴的 Bean 對象

我們來簡單回顧一下

  1. 通過 @Bean 聲明 bean,把 bean 存在 Spring 容器中
public class Dog {  
    private String name;  
    public void setName(String name) {  
        this.name = name;  
    }  
}
@Component  
public class DogBeanConfig {  
    @Bean  
    public Dog dog() {  
        Dog dog = new Dog();  
        dog.setName("旺旺");  
        return dog;  
    }  
}
  1. Spring 容器中獲取 Bean
    • 通過在代碼中直接注入 ApplicationContext 的方式
@SpringBootTest  
class ApplicationTests {  
    @Autowired  
    private ApplicationContext applicationContext;  
    @Test  
    void contextLoads() {  
        DogBeanConfig dog1 = applicationContext.getBean(DogBeanConfig.class);;  
        System.out.println(dog1);  
    }  
}

司改代碼,從 Spring 容器中多次獲取 Bean

@SpringBootTest  
class ApplicationTests {  
    @Autowired  
    private ApplicationContext applicationContext;  
    @Test  
    void contextLoads() {  
        DogBeanConfig dog1 = applicationContext.getBean(DogBeanConfig.class);;  
        System.out.println(dog1);  
        DogBeanConfig dog2 = applicationContext.getBean(DogBeanConfig.class);;  
        System.out.println(dog2);  
    }  
}

觀察運(yùn)行結(jié)果

發(fā)現(xiàn)輸出的 bean 對象地址是一樣的,說明每次從 Spring 容器中取出來的對象都是同一個(gè)

  • 這也是“單例模式
  • 單例模式:確保一個(gè)類只有一個(gè)實(shí)例,多次創(chuàng)建也不會(huì)創(chuàng)建出多個(gè)實(shí)例

Bean 的作用域是值 BeanSpring 框架中的某種行為模式

比如單例作用域:表示 Bean 在整個(gè) Spring 中只有一份,它是全局共享的。那么當(dāng)其他人修改了這個(gè)值之后,那么另一個(gè)人讀到的就是被修改后的值

修改上述代碼,給 UserController 添加屬性 name

@SpringBootTest  
class ApplicationTests {  
    @Autowired  
    private ApplicationContext applicationContext;  
    @Test  
    void contextLoads() {  
        Dog dog1 = applicationContext.getBean(Dog.class);  
        dog1.setName("狗狗1");  
        System.out.println(dog1);  
        System.out.println(dog1.getName());  
        Dog dog2 = applicationContext.getBean(Dog.class);;  
        System.out.println(dog2);  
        System.out.println(dog2.getName());  
    }  
}

觀察運(yùn)行結(jié)果:

  • dog1dog2 為同一個(gè)對象,dog2 拿到了 dog1 設(shè)置的值

那能不能將 bean 對象設(shè)置為非單例的(每次獲取的 bean 都是一個(gè)新對象呢)

  • 這就是 Bean 的不同作用域了

Bean 的作用域

Spring 中支持 6 中作用域,后 4 種在 Spring MVC 環(huán)境才生效

  1. singleton:單例作用域
    • 每個(gè) Spring Ioc 容器內(nèi)同名稱的 Bean 只有一個(gè)實(shí)例(單例)(默認(rèn))
  2. prototype:原型作用域(多例作用域)
    • 每次使用該 bean 時(shí)會(huì)創(chuàng)建新的實(shí)例(非單例)
  3. request:請求作用域
    • 每個(gè) HTTP 請求生命周期內(nèi),創(chuàng)建新的實(shí)例(Web 環(huán)境中,了解)
  4. session:會(huì)話作用域
    • 每個(gè) HTTP Session 生命周期內(nèi),創(chuàng)建新的實(shí)例(Web 環(huán)境中,了解)
  5. Application:全局作用域
    • 每個(gè) ServletContext 生命周期里內(nèi),創(chuàng)建新的實(shí)例(web 環(huán)境中,了解)
  6. websocketHTTP WebSocket 作用域
    • 每個(gè) WebSocket 生命周期內(nèi),創(chuàng)建新的實(shí)例(web 環(huán)境中,了解)

我們來看簡單的代碼實(shí)現(xiàn)

定義幾個(gè)不同作用域的 bean

@Component  
public class DogBeanConfig {  
    @Bean  
    public Dog dog() {  
        Dog dog = new Dog();  
        dog.setName("旺旺");  
        return dog;  
    }  
    @Bean  
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)  
    public Dog singleDog() {  
        Dog dog = new Dog();  
        return dog;  
    }  
    @Bean  
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)  
    public Dog prototype() {  
        Dog dog = new Dog();  
        return dog;  
    }  
    @Bean  
    @RequestScope    
    public Dog requestDog() {  
        Dog dog = new Dog();  
        return dog;  
    }  
    @Bean  
    @SessionScope    
    public Dog sessionDog() {  
        Dog dog = new Dog();  
        return dog;  
    }  
    @Bean  
    @ApplicationScope    
    public Dog applicationDog() {  
        Dog dog = new Dog();  
        return dog;  
    }  
}
  • @RequestScope 等同于 @Scope (value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
  • @SessionScope 等同于 @Scope (value =WebApplicationContext.SCOPE_SESSION, proxyMode =ScopedProxyMode.TARGET_CLASS)
  • @ApplicationScope 等同于 @Scope (value =WebApplicationContext. SCOPE_APPLICATION, proxyMode =ScopedProxyMode. TARGET_CLASS)

proxyMode ?來為 springbean 設(shè)置代理 .proxyMode = ScopedProxyMode.TARGET_CLASS 表?這個(gè) Bean 基于 CGLIB 實(shí)現(xiàn)動(dòng)態(tài)代理,Request,sessionapplication 作?域的 Bean 需要設(shè)置 proxyMode

代碼測試

測試不同作用域的 bean 取到的對象是否一樣

@RestController  
public class DogController {  
    @Autowired  
    private Dog singleDog;  
    @Autowired  
    private Dog prototypeDog;  
    @Autowired  
    private Dog requestDog;  
    @Autowired  
    private Dog sessionDog;  
    @Autowired  
    private Dog applicationDog;  
    @Autowired  
    private ApplicationContext applicationContext;  
    @RequestMapping("/single")  
    public String single(){  
        Dog contexDog = (Dog) applicationContext.getBean("singleDog");  
        return "dog: " + singleDog.toString() + ", contextDog: " + contexDog;  
    }  
    @RequestMapping("/prototype")  
    public String prototype() {  
        Dog contextDog = (Dog) applicationContext.getBean("prototypeDog");  
        return "dog: " + prototypeDog.toString() + ", contextDog: " + contextDog;  
    }  
    @RequestMapping("/request")  
    public String request(){  
        Dog contexDog = (Dog) applicationContext.getBean("requestDog");  
        return "dog: " + requestDog.toString() + ", contextDog: " + contexDog;  
    }  
    @RequestMapping("/session")  
    public String session() {  
        Dog contextDog = (Dog) applicationContext.getBean("sessionDog");  
        return "dog: " + sessionDog.toString() + ", contextDog: " + contextDog;  
    }  
    @RequestMapping("/application")  
    public String application() {  
        Dog contextDog = (Dog) applicationContext.getBean("applicationDog");  
        return "dog: " + applicationDog.toString() + ", contextDog: " + contextDog;  
    }  
}
  • 每個(gè)請求都獲取兩次 Bean
  • @AutowiredapplicationContext.getBean("singleDog") 都是從 Spring 容器中獲取對象

觀察 Bean 的作用域

1.單例作用域

地址: http://127.0.0.1:8080/single

多次訪問,得到的都是同一個(gè)對象,并且 @AutowiredapplicationContext.getBean() 也是同一個(gè)對象

2.多例作用域

地址: http://127.0.0.1:8080/prototype

觀察 ContextDog,每次獲取的對象都不一樣(注入的對象在 Spring 容器啟動(dòng)時(shí),就已經(jīng)注入了,所以多次請求訪問也不會(huì)發(fā)生變化)

3.請求作用域

地址: http://127.0.0.1:8080/request

在一次請求中,@AutowiredapplicationContext.getBean() 也是同一個(gè)對象,但是每次請求,都會(huì)重新創(chuàng)建對象

4.會(huì)話作用域

地址: http://127.0.0.1:8080/session

在一個(gè) session 中,多次請求,獲取到的對象都是同一個(gè)

換一個(gè)瀏覽器訪問,發(fā)現(xiàn)會(huì)重新創(chuàng)建對象(另一個(gè) session

5.Application作用域

地址: http://127.0.0.1:8080/application

在一個(gè)應(yīng)用中,多次訪問都是同一個(gè)對象

  • Application scope 就是對于整個(gè) web 容器來說,bean 的作用域是 ServletContext 級(jí)別的
  • 這個(gè)和 singleton 有點(diǎn)類似,區(qū)別在于:Application scopeServletContext 的單例,singleton 是一個(gè) ApplicationContext 的單例
  • 在一個(gè) web 容器中 ApplicationContext 可以有多個(gè)(了解即可)

到此這篇關(guān)于Spring Bean的作用域具體實(shí)現(xiàn)(單例、多例、請求、會(huì)話、Application)的文章就介紹到這了,更多相關(guān)Spring Bean作用域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java微信公眾號(hào)推送模版消息的步驟示例詳解

    Java微信公眾號(hào)推送模版消息的步驟示例詳解

    模板消息是一種向用戶發(fā)送通知的服務(wù),廣泛用于訂單狀態(tài)更新、服務(wù)提醒等場景,下面,我將詳細(xì)介紹如何使用Java結(jié)合微信官方提供的API來實(shí)現(xiàn)模板消息的推送,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • Java如何優(yōu)雅地避免空指針異常(NullPointerException)

    Java如何優(yōu)雅地避免空指針異常(NullPointerException)

    這篇文章主要給大家介紹了關(guān)于Java如何優(yōu)雅地避免空指針異常(NullPointerException)的相關(guān)資料,空指針異常(NullPointerException)是一種常見的運(yùn)行時(shí)異常,它在Java編程中經(jīng)常出現(xiàn),需要的朋友可以參考下
    2024-03-03
  • spring入門教程之bean的繼承與自動(dòng)裝配詳解

    spring入門教程之bean的繼承與自動(dòng)裝配詳解

    眾所周知Spring里面的bean就類似是定義的一個(gè)組件,而這個(gè)組件的作用就是實(shí)現(xiàn)某個(gè)功能的,下面這篇文章主要給大家介紹了關(guān)于spring入門教程之bean繼承與自動(dòng)裝配的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Java實(shí)現(xiàn)統(tǒng)計(jì)在線人數(shù)功能的方法詳解

    Java實(shí)現(xiàn)統(tǒng)計(jì)在線人數(shù)功能的方法詳解

    很多人在筆試或者面試中問到:現(xiàn)在要你實(shí)現(xiàn)一個(gè)統(tǒng)計(jì)在線人數(shù)的功能,你該怎么設(shè)計(jì)?不知道的朋友,這篇文章就來告訴你具體實(shí)現(xiàn)方法
    2022-08-08
  • java: 程序包c(diǎn)om.fasterxml.jackson.annotation不存在的解決辦法

    java: 程序包c(diǎn)om.fasterxml.jackson.annotation不存在的解決辦法

    當(dāng)我們在導(dǎo)入程序之后,系統(tǒng)給出錯(cuò)誤提示:java: 程序包c(diǎn)om.fasterxml.jackson.annotation不存在,本文主要介紹了Java程序包不存在的三種解決方法,需要的朋友可以參考下
    2024-02-02
  • Java根據(jù)url生成圖片、截圖效果

    Java根據(jù)url生成圖片、截圖效果

    文章詳細(xì)介紹了如何使用Java和Node.js結(jié)合Puppeteer庫根據(jù)URL截圖,并將圖片轉(zhuǎn)換為標(biāo)準(zhǔn)輸出流返回給Java程序,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法

    Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法

    本文主要介紹了Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • spring boot 啟動(dòng)過程步驟詳解

    spring boot 啟動(dòng)過程步驟詳解

    本文分步驟給大家介紹了spring boot 啟動(dòng)過程,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-11-11
  • Java中throws?與?throw?的區(qū)別與用法示例詳解

    Java中throws?與?throw?的區(qū)別與用法示例詳解

    本文給大家介紹Java中throws與throw的區(qū)別與用法示例詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-09-09
  • 高級(jí)數(shù)據(jù)結(jié)構(gòu)及應(yīng)用之使用bitmap進(jìn)行字符串去重的方法實(shí)例

    高級(jí)數(shù)據(jù)結(jié)構(gòu)及應(yīng)用之使用bitmap進(jìn)行字符串去重的方法實(shí)例

    今天小編就為大家分享一篇關(guān)于高級(jí)數(shù)據(jù)結(jié)構(gòu)及應(yīng)用之使用bitmap進(jìn)行字符串去重的方法實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02

最新評(píng)論

通化市| 揭西县| 古田县| 新巴尔虎右旗| 湘潭县| 工布江达县| 雅安市| 彝良县| 称多县| 宣威市| 东乡| 瑞丽市| 金沙县| 博湖县| 开江县| 花垣县| 宜兴市| 邯郸县| 察隅县| 平南县| 当涂县| 农安县| 馆陶县| 双桥区| 惠东县| 大庆市| 准格尔旗| 晋中市| 克拉玛依市| 彭阳县| 南澳县| 河东区| 弋阳县| 石景山区| 富民县| 九江市| 平谷区| 固镇县| 奇台县| 平山县| 宜阳县|