欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過(guò)spring注解開(kāi)發(fā),簡(jiǎn)單測(cè)試單例和多例區(qū)別

 更新時(shí)間:2021年08月23日 10:42:13   作者:hz90s  
這篇文章主要介紹了通過(guò)spring注解開(kāi)發(fā),簡(jiǎn)單測(cè)試單例和多例區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

通過(guò)spring注解開(kāi)發(fā),測(cè)試單例和多例區(qū)別

1.注解和配置兩種用法形式

配置版:

注解版:

2.在spring框架中,scope作用域默認(rèn)是單例的

注:以下測(cè)試均是注解版

3.實(shí)例

(1)多例:

配置類:

@Configuration
public class PersonConfigure {
     //給容器中注冊(cè)一個(gè)bean,類型為返回值的類型,id為方法名
   @Scope("prototype") //多例
   @Bean()
   public Person person() {
        System.out.println("bean被加載到容器中");
     return new Person("張三",23);
   }
}

單元測(cè)試:

@Test
public void test02() {
     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PersonConfigure.class);
     System.out.println("ioc容器加載完成");
     Person bean = (Person) context.getBean("person");
     bean.setName("lisi");
     System.out.println(bean.toString());
     Person bean1 = (Person) context.getBean("person");
     System.out.println(bean1.toString());
     System.out.println(bean==bean1);
}
}

測(cè)試結(jié)果:

結(jié)論:多例情況下,容器創(chuàng)建完成時(shí)不調(diào)用方法創(chuàng)建對(duì)象到容器中,在程序中獲取時(shí),才會(huì)將對(duì)象加載到容器中,而且每次調(diào)用生成的都是不同的對(duì)象。

(2)單例(注解版)

配置類:

//默認(rèn)是單例
@Configuration
public class PersonConfigure {
     //給容器中注冊(cè)一個(gè)bean,類型為返回值的類型,id為方法名
   @Bean()
   public Person person() {
    System.out.println("bean被加載到容器中");
     return new Person("張三",23);
   }
}

單元測(cè)試:

@Test
public void test02() {
     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PersonConfigure.class);
     System.out.println("ioc容器加載完成");
     Person bean = (Person) context.getBean("person");
     bean.setName("lisi");
     System.out.println(bean.toString());
     Person bean1 = (Person) context.getBean("person");
     System.out.println(bean1.toString());
     System.out.println(bean==bean1);
}
}

測(cè)試結(jié)果:

結(jié)論:?jiǎn)卫闆r下,容器創(chuàng)建時(shí)調(diào)用方法創(chuàng)建對(duì)象到容器中,在程序中調(diào)用bean,直接從容器中拿取,且每次拿取的都是同一個(gè)對(duì)象。如果上一次對(duì)bean里的屬性做了修改,那下一次拿取的就是修改過(guò)的bean。

Spring中單例和多例的理解

1、什么是單例和多例

單例:所有請(qǐng)求用同一個(gè)對(duì)象來(lái)處理。通過(guò)單例模式,可以保證系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例。

多例:每個(gè)請(qǐng)求用一個(gè)新的對(duì)象來(lái)處理。

2、Spring中的單例與多例

spring ioc容器的bean都是默認(rèn)單例的,即spring依賴注入Bean實(shí)例默認(rèn)是單例的。

spring提供了5中scope,分別是singleton,prototype,request,session,global session,常用是前兩種。點(diǎn)此查看官網(wǎng)介紹。

單例bean與多例(原型)bean的區(qū)別:

如果一個(gè)bean被聲明為單例的時(shí)候,在處理多次請(qǐng)求的時(shí)候,在spring容器里只實(shí)例化出一個(gè)bean,后續(xù)的請(qǐng)求都公用這個(gè)對(duì)象,這個(gè)對(duì)象會(huì)保存在一個(gè)map里面。當(dāng)有請(qǐng)求來(lái)的時(shí)候,會(huì)先從緩存(map)里查看有沒(méi)有,有的話直接使用這個(gè)對(duì)象,沒(méi)有的話才實(shí)例化一個(gè)新的對(duì)象,所以這是個(gè)單例的。但是對(duì)于原型(prototype)bean來(lái)說(shuō),當(dāng)每次請(qǐng)求來(lái)的時(shí)候,會(huì)直接實(shí)例化新的bean,沒(méi)有緩存以及緩存查詢的過(guò)程。

3、單例的優(yōu)勢(shì)與劣勢(shì)

優(yōu)勢(shì):

由于不會(huì)創(chuàng)建新的對(duì)象,所以有以下幾個(gè)性能上的優(yōu)勢(shì):

減少新生成實(shí)例的消耗。新生成實(shí)例包括兩個(gè)方面,第一,spring會(huì)通過(guò)反射或者cglib來(lái)生成bean實(shí)例,這都是耗性能的操作。第二,給對(duì)象分配內(nèi)存也會(huì)涉及負(fù)責(zé)算法。

減少jvm垃圾回收。由于不會(huì)給每個(gè)請(qǐng)求都生成bean實(shí)例,所以回收的對(duì)象就少了。

可以快速獲取到bean。因?yàn)閱卫@取bean操作,除了第一次生成之外,其余都是從緩存里獲取的,所以很快。

劣勢(shì):

一個(gè)很大的劣勢(shì)是它不能做到線程安全。由于所有請(qǐng)求都共享一個(gè)bean實(shí)例,那么如果這個(gè)bean是一個(gè)有狀態(tài)的bean的話,在并發(fā)場(chǎng)景下就有可能出現(xiàn)問(wèn)題。

4、spring單例模式與線程安全:

當(dāng)多用戶同時(shí)請(qǐng)求一個(gè)服務(wù)時(shí),容器會(huì)給每一個(gè)請(qǐng)求分配一個(gè)線程,這時(shí)多個(gè)線程會(huì)并發(fā)執(zhí)行該請(qǐng)求所對(duì)應(yīng)的業(yè)務(wù)邏輯(成員方法),此時(shí)就要注意了,如果該處理邏輯中有對(duì)該單例狀態(tài)的修改(體現(xiàn)為該單例的成員屬性),則必須考慮線程同步問(wèn)題(此時(shí)該狀態(tài)就是一個(gè)臨界資源(共享數(shù)據(jù)),如果多個(gè)線程同時(shí)操作(修改)這個(gè)臨界資源就會(huì)誘發(fā)線程安全問(wèn)題)。

線程安全:如果你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行的結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的?;蛘哒f(shuō):一個(gè)類或者程序所提供的接口對(duì)于線程來(lái)說(shuō)是原子操作,或者多線程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,就是線程安全的。

線程安全問(wèn)題都是由全局變量及靜態(tài)變量引起的。

若每個(gè)線程中對(duì)全局變量,靜態(tài)變量只有讀操作,而無(wú)寫(xiě)操作,一般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若多個(gè)線程同時(shí)執(zhí)行寫(xiě)操作,一般都需要考慮線程同步,否則就可能影響線程安全。

常量始終是線程安全的,因?yàn)橹淮嬖谧x操作;

每次調(diào)用方法前都新建一個(gè)實(shí)例是線程安全的,因?yàn)椴粫?huì)訪問(wèn)共享的資源;

局部變量是線程安全的。因?yàn)槊繄?zhí)行一個(gè)方法,都會(huì)在獨(dú)立的空間創(chuàng)建局部變量,它不是共享資源。局部變量包括方法的參數(shù)變量和方法內(nèi)的變量。

在關(guān)于spring單例與線程安全的很多文章中,會(huì)提到一個(gè)概念,即有狀態(tài)bean和無(wú)狀態(tài)bean。

  • 無(wú)狀態(tài)bean:無(wú)狀態(tài),就是一次操作,不能保存數(shù)據(jù)。無(wú)狀態(tài)bean,就是沒(méi)有實(shí)例變量的對(duì)象,不能保存數(shù)據(jù),是不變類,在線程安全的。
  • 有狀態(tài)bean:有狀態(tài),就是有數(shù)據(jù)存儲(chǔ)功能。有狀態(tài)bean,就是有實(shí)例變量的對(duì)象,可以保存數(shù)據(jù),是非線程安全的。

如何解決線程安全問(wèn)題?

(1)使用線程同步機(jī)制:通過(guò)對(duì)象的鎖機(jī)制保證同一時(shí)間只有一個(gè)線程訪問(wèn)變量。這時(shí)該變量是多個(gè)線程共享的,使用同步機(jī)制要求程序縝密地分析什么時(shí)候?qū)ψ兞窟M(jìn)行讀寫(xiě),什么時(shí)候需要鎖定某個(gè)對(duì)象,什么時(shí)候釋放對(duì)象鎖等繁雜問(wèn)題,程序設(shè)計(jì)和編寫(xiě)難度相對(duì)較大。

(2)使用ThreadLocal:為每一個(gè)線程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線程對(duì)數(shù)據(jù)的訪問(wèn)沖突。因?yàn)槊恳粋€(gè)線程都擁有自己的變量副本,從而也就沒(méi)有必要對(duì)該變量進(jìn)行同步了。

概括起來(lái)就是:對(duì)于多線程資源共享的問(wèn)題,同步機(jī)制采用了“以時(shí)間換空間”的方式,而ThreadLocal采用了“以空間換時(shí)間”的方式。前者僅提供一份變量,讓不同的線程排隊(duì)訪問(wèn),而后者為每一個(gè)線程都提供了一份變量,因此可以同時(shí)訪問(wèn)而互不影響。

5、單例如何變多例

Scope聲明為prototype,即

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中Set&List的迭代器實(shí)現(xiàn)步驟解析

    Java中Set&List的迭代器實(shí)現(xiàn)步驟解析

    這篇文章主要介紹了Java中Set&List的迭代器實(shí)現(xiàn)步驟解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • 在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解

    在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解

    這篇文章主要介紹了在?Spring?Boot?中使用?Quartz?調(diào)度作業(yè)的示例詳解,在本文中,我們將看看如何使用Quartz框架來(lái)調(diào)度任務(wù),Quartz支持在特定時(shí)間運(yùn)行作業(yè)、重復(fù)作業(yè)執(zhí)行、將作業(yè)存儲(chǔ)在數(shù)據(jù)庫(kù)中以及Spring集成,需要的朋友可以參考下
    2022-07-07
  • Spring Bean生命周期之Bean的實(shí)例化詳解

    Spring Bean生命周期之Bean的實(shí)例化詳解

    這篇文章主要為大家詳細(xì)介紹了Spring Bean生命周期之Bean的實(shí)例化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • Jmeter邏輯控制器事務(wù)控制器使用方法解析

    Jmeter邏輯控制器事務(wù)控制器使用方法解析

    這篇文章主要介紹了Jmeter邏輯控制器事務(wù)控制器使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot @ExceptionHandler與@ControllerAdvice異常處理詳解

    SpringBoot @ExceptionHandler與@ControllerAdvice異常處理詳解

    在Spring Boot應(yīng)用的開(kāi)發(fā)中,不管是對(duì)底層數(shù)據(jù)庫(kù)操作,對(duì)業(yè)務(wù)層操作,還是對(duì)控制層操作,都會(huì)不可避免的遇到各種可預(yù)知的,不可預(yù)知的異常需要處理,如果每個(gè)處理過(guò)程都單獨(dú)處理異常,那么系統(tǒng)的代碼耦合度會(huì)很高,工作量大且不好統(tǒng)一,以后維護(hù)的工作量也很大
    2022-10-10
  • IDEA設(shè)置生成帶注釋的getter和setter的圖文教程

    IDEA設(shè)置生成帶注釋的getter和setter的圖文教程

    通常我們用idea默認(rèn)生成的getter和setter方法是不帶注釋的,當(dāng)然,我們同樣可以設(shè)置idea像MyEclipse一樣生成帶有Javadoc的模板,具體設(shè)置方法,大家參考下本文
    2018-05-05
  • Java創(chuàng)建ZIP壓縮文件的方法

    Java創(chuàng)建ZIP壓縮文件的方法

    這篇文章主要介紹了Java創(chuàng)建ZIP壓縮文件的方法,實(shí)例分析了java創(chuàng)建zip文件的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • JAVA編程不能不知道的反射用法總結(jié)

    JAVA編程不能不知道的反射用法總結(jié)

    這篇文章主要介紹了Java反射技術(shù)原理與用法,結(jié)合實(shí)例形式分析了Java反射技術(shù)的基本概念、功能、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2021-07-07
  • 對(duì)Java字符串與整形、浮點(diǎn)類型之間的相互轉(zhuǎn)換方法總結(jié)

    對(duì)Java字符串與整形、浮點(diǎn)類型之間的相互轉(zhuǎn)換方法總結(jié)

    今天小編就為大家分享一篇對(duì)Java字符串與整形、浮點(diǎn)類型之間的相互轉(zhuǎn)換方法總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • SpringBoot項(xiàng)目的測(cè)試類實(shí)例解析

    SpringBoot項(xiàng)目的測(cè)試類實(shí)例解析

    這篇文章主要介紹了SpringBoot項(xiàng)目的測(cè)試類實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12

最新評(píng)論