Spring中的@Scope注解詳細(xì)講解及示例
1.@Scope注解是什么
@Scope注解是 Spring IOC 容器中的一個作用域,在 Spring IOC 容器中,他用來配置Bean實(shí)例的作用域?qū)ο蟆?/p>
@Scope 具有以下幾種作用域:
- singleton 單實(shí)例的(單例)(默認(rèn)) ----全局有且僅有一個實(shí)例
- prototype 多實(shí)例的(多例) ---- 每次獲取Bean的時候會有一個新的實(shí)例
- reqeust 同一次請求 ----request:每一次HTTP請求都會產(chǎn)生一個新的bean,同時該bean僅在當(dāng)前HTTP request內(nèi)有效
- session 同一個會話級別 ---- session:每一次HTTP請求都會產(chǎn)生一個新的bean,同時該bean僅在當(dāng)前HTTP session內(nèi)有效
注:這邊只演示我們常用的 singleton、prototype 兩種,其他的可以自己試試
2.@Scope注解怎么使用
直接在bean對象方法上增加@Scope注解即可。
① 在不指定@Scope的情況下,所有的bean都是單實(shí)例的bean,而且是餓漢模式加載(容器啟動實(shí)例就創(chuàng)建好了)
@Bean
public Person person() {
return new Person();
}
②指定@Scope為 prototype 表示為多實(shí)例的,而且還是懶漢模式加載(IOC容器啟動的時候,并不會創(chuàng)建對象,而是 在第一次使用的時候才會創(chuàng)建)
@Bean
@Scope(value = "prototype")
public Person person() {
return new Person();
}
3.singleton/prototype模式演示
/**
* Person類
*/
public class Person {
// Person類無參構(gòu)造方法
public Person() {
System.out.println("執(zhí)行Person構(gòu)造器創(chuàng)建Person對象");
}
}
/**
* TODO 主配置類
*
* @author : lzb
* @date: 2021-03-05 13:50
*/
@Configuration
public class BeanConfig {
@Bean
@Scope(value = "singleton")
public Person person(){
return new Person();
}
}
3.1 singleton單例演示
@Scope注解默認(rèn)為singleton單例,singleton實(shí)例的意思不管你使用多少次在springIOC容器中只會存在一個實(shí)例,演示如下只打印了一次創(chuàng)建實(shí)例:
public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(BeanConfig.class);
Person person = ac.getBean(Person.class);
Person person2 = ac.getBean(Person.class);
System.out.println(person);
System.out.println(person2);
System.out.println(person == person2);
}
}
執(zhí)行結(jié)果:

可以發(fā)現(xiàn)singleton單例模式,在IOC容器中只會有一個實(shí)例存在,每次getBean()獲取的實(shí)例對象都是同一個。
3.2 prototype多例演示
/**
* TODO 主配置類
*
* @author : lzb
* @date: 2021-03-05 13:50
*/
@Configuration
public class BeanConfig {
@Bean
@Scope(value = "prototype")
public Person person(){
return new Person();
}
}
執(zhí)行結(jié)果:

發(fā)現(xiàn)prototype多例模式,每次在調(diào)用getBean() 獲取實(shí)例時,都會重新調(diào)用 Person 類的無參構(gòu)造方法,重新創(chuàng)建一個 Person 對象。
4.惡漢/懶漢
使用singleton單例,采用餓漢加載(容器啟動,Bean實(shí)例就創(chuàng)建好了)
使用prototype多例,采用懶漢加載(IOC容器啟動的時候,并不會創(chuàng)建對象實(shí)例,而是在第一次使用的時候才會創(chuàng)建)
4.1 singleton 惡漢
演示
/**
* TODO 主配置類
*
* @author : lzb
* @date: 2021-03-05 13:50
*/
@Configuration
public class BeanConfig {
@Bean
@Scope(value = "singleton")
public Person person(){
return new Person();
}
}
public class DemoApplication {
public static void main(String[] args) {
// 啟動Spring IOC容器
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(BeanConfig.class);
}
}
執(zhí)行結(jié)果:

singleton單例模式,在 IOC 容器啟動時,便會去調(diào)用 Person 類的無參構(gòu)造方法,創(chuàng)建一個 Person 對象。此時并沒有調(diào)用 getBean() 方法來獲取Person 對象實(shí)例。
所以singleton 采用的是 惡漢式 創(chuàng)建實(shí)例對象
注:如何將 singleton 單例模式的 惡漢式 變更為 懶漢式,只需要再添加一個 @Lazy 注解即可。 如下所示:
@Configuration
public class BeanConfig {
@Bean
@Scope
@Lazy
public Person person(){
return new Person();
}
}
4.2 prototype 懶漢
演示
/**
* TODO 主配置類
*
* @author : lzb
* @date: 2021-03-05 13:50
*/
@Configuration
public class BeanConfig {
@Bean
@Scope(value = "prototype")
public Person person(){
return new Person();
}
}
public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println("=================IOC容器啟動成功==============");
Person person = ac.getBean(Person.class);
System.out.println(person);
}
}
執(zhí)行結(jié)果:

prototype多例模式,在 IOC 容器啟動時,并不會去創(chuàng)建Bean實(shí)例,只有在調(diào)用 getBean() 方法獲取Person 對象時,才會去調(diào)用 Person 類的無參構(gòu)造方法,創(chuàng)建一個 Person 對象。
所以 prototype 采用的是 懶漢式 創(chuàng)建實(shí)例對象
5.Bean實(shí)例對象的銷毀
針對單實(shí)例bean的話,容器啟動的時候,bean的對象就創(chuàng)建了,而且容器銷毀的時候,也會調(diào)用Bean的銷毀方法;
針對多實(shí)例bean的話,容器啟動的時候,bean是不會被創(chuàng)建的而是在獲取bean的時候被創(chuàng)建,而且bean的銷毀不受IOC容器的管理,是由GC來處理的
針對每一個Bean實(shí)例,都會有一個initMethod() 和 destroyMethod() 方法,我們可以在Bean 類中自行定義,也可以使用 Spring 默認(rèn)提供的這兩個方法。
public class Person {
public Person() {
System.out.println("執(zhí)行Person構(gòu)造器創(chuàng)建Person對象");
}
public void init() {
System.out.println("initMethod");
}
public void destroy() {
System.out.println("destroyMethod");
}
}
@Configuration
public class BeanConfig {
@Bean(initMethod = "init", destroyMethod = "destroy") // 可以自己指定方法名,也可以不指定,使用Spring默認(rèn)提供的方法
@Scope(value = "singleton")
public Person person(){
return new Person();
}
}
singleton單例,在IOC容器銷毀時,就會調(diào)用 destroyMethod() 方法來將 Bean對象銷毀;prototype多例,它的Bean實(shí)例對象則不受IOC容器的管理,最終由GC來銷毀。
6.@Scope注解的使用場景
幾乎90%以上的業(yè)務(wù)使用 singleton單例就可以,所以 Spring 默認(rèn)的類型也是singleton,singleton雖然保證了全局是一個實(shí)例,對性能有所提高,但是如果實(shí)例中有非靜態(tài)變量時,會導(dǎo)致線程安全問題,共享資源的競爭。
當(dāng)設(shè)置為prototype多例時:每次連接請求,都會生成一個bean實(shí)例,也會導(dǎo)致一個問題,當(dāng)請求數(shù)越多,性能會降低,因?yàn)閯?chuàng)建的實(shí)例,導(dǎo)致GC頻繁,GC時長增加。
到此這篇關(guān)于Spring中的@Scope注解詳細(xì)講解及示例的文章就介紹到這了,更多相關(guān)Spring中的@Scope注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
將JavaWeb項(xiàng)目部署到云服務(wù)器的詳細(xì)步驟
這篇文章主要介紹了將JavaWeb項(xiàng)目部署到云服務(wù)器的詳細(xì)步驟,文章通過圖文結(jié)合的方式給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-12-12
springboot解決Class path contains multiple 
這篇文章主要介紹了springboot解決Class path contains multiple SLF4J bindings問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
Java讀寫pdf文件的詳細(xì)實(shí)現(xiàn)方法
最近公司的項(xiàng)目中需要操作pdf文件,所以這里給大家總結(jié)下方法,這篇文章主要給大家介紹了關(guān)于Java讀寫pdf文件的詳細(xì)實(shí)現(xiàn)方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
NameNode?重啟恢復(fù)數(shù)據(jù)的流程詳解
這篇文章主要為大家介紹了NameNode?重啟恢復(fù)數(shù)據(jù)的流程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
SpringBoot數(shù)據(jù)校驗(yàn)功能的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot數(shù)據(jù)校驗(yàn)功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02
使用kotlin編寫spring cloud微服務(wù)的過程
這篇文章主要介紹了使用kotlin編寫spring cloud微服務(wù)的相關(guān)知識,本文給大家提到配置文件的操作代碼,給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09
Spring-boot 2.3.x源碼基于Gradle編譯過程詳解
這篇文章主要介紹了Spring-boot 2.3.x源碼基于Gradle編譯過程詳解,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
SpringBoot Maven打包插件spring-boot-maven-plugin無法解析原因
spring-boot-maven-plugin是spring boot提供的maven打包插件,本文主要介紹了SpringBoot Maven打包插件spring-boot-maven-plugin無法解析原因,具有一定的參考價值,感興趣的可以了解一下2024-03-03
java學(xué)生管理系統(tǒng)界面簡單實(shí)現(xiàn)(全)
這篇文章主要為大家詳細(xì)介紹了java學(xué)生管理系統(tǒng)界面的簡單實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

