Spring 的 Controller 是單例還是多例?怎麼保證並發的安全

2021-01-17 ImportNew

(給ImportNew加星標,提高Java技能)

轉自:riemann_ 來源 

連結:blog.csdn.net/riemann_/article/details/97698560

controller默認是單例的,不要使用非靜態的成員變量,否則會發生數據邏輯混亂。正因為單例所以不是線程安全的。

我們下面來簡單的驗證下:

package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author riemann
 * @date 2019/07/29 22:56
 */
@Controller
public class ScopeTestController {

    private int num = 0;

    @RequestMapping("/testScope")
    public void testScope() {
        System.out.println(++num);
    }

    @RequestMapping("/testScope2")
    public void testScope2() {
        System.out.println(++num);
    }

}


我們首先訪問 http://localhost:8080/testScope,得到的答案是1;然後我們再訪問 http://localhost:8080/testScope2,得到的答案是 2。


得到的不同的值,這是線程不安全的。


接下來我們再來給controller增加作用多例 @Scope("prototype")


package com.riemann.springbootdemo.controller;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author riemann
 * @date 2019/07/29 22:56
 */
@Controller
@Scope("prototype")
public class ScopeTestController {

    private int num = 0;

    @RequestMapping("/testScope")
    public void testScope() {
        System.out.println(++num);
    }

    @RequestMapping("/testScope2")
    public void testScope2() {
        System.out.println(++num);
    }

}


我們依舊首先訪問 http://localhost:8080/testScope,得到的答案是1;然後我們再訪問 http://localhost:8080/testScope2,得到的答案還是 1。


相信大家不難發現 :


單例是不安全的,會導致屬性重複使用。

推薦一個DD寫的SpringBoot基礎教程:http://blog.didispace.com/spring-boot-learning-2x/解決方案


1、不要在controller中定義成員變量。2、萬一必須要定義一個非靜態成員變量時候,則通過註解@Scope(「prototype」),將其設置為多例模式。3、在Controller中使用ThreadLocal變量


補充說明


spring bean作用域有以下5個:


singleton:單例模式,當spring創建applicationContext容器的時候,spring會欲初始化所有的該作用域實例,加上lazy-init就可以避免預處理;

prototype:原型模式,每次通過getBean獲取該bean就會新產生一個實例,創建後spring將不再對其管理;

(下面是在web項目下才用到的)

request:搞web的大家都應該明白request的域了吧,就是每次請求都新產生一個實例,和prototype不同就是創建後,接下來的管理,spring依然在監聽;

global session:全局的web域,類似於servlet中的application。



看完本文有收穫?請轉發分享給更多人

關注「ImportNew」,提升Java技能

好文章,我在看❤️

相關焦點

  • 基於Spring Boot + MVC 之控制器Controller實現
    在src-main-java下面,找到com.zzfeng.springbootdemo這個包,在這個包上面右擊,再分別點擊New-Package,進入創建包的面板。在New Package面板上輸入包名controller,完成包的創建。創建成功後,會在com.zzfeng.springbootdemo下面出現一個名叫controller的包。
  • Java經典面試題Spring是什麼 Spring框架入門詳解
    新建一個pojo類User2並在User中作為變量引入,xml中新增一個bean user2,將User2對象交給spring創建,在User的Bean配置user2的引用,property的name還是變量名,這裡的value要換成ref,ref為要引用的對象的bean的name
  • 14個編寫Spring MVC控制器的實用小技巧
    1.使用@controllerstereotype創建一個能夠處理單個或多個請求的控制器類,最簡單的方法就是使用@controllerstereotype註解一個類,如:import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping
  • 程式設計師:java單例模式,為什麼要加雙重鎖?為什麼要加volatile?
    單例模式單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。
  • Spring Boot 示例的@RestController 和 @RequestMapping註解
    Spring 有多個類型的註解,例如在包 org.springframework.context.annotation 和 org.springframework.stereotype 的註解。非常簡單來說@RestController 是一個特殊版本的 controller。是由 @Controller 和 @ResponseBody 2 個註解合併而成的。 在沒有 @RestController 註解之前,你可以使用 @Controller ,同時你還需要使用 @ResponseBody 註解來確定返回的內容是什麼。
  • 俄羅斯單日新增2186例新冠肺炎確診病例,累計15770例
    俄羅斯單日新增2186例新冠肺炎確診病例,累計15770例 2020-04-12 15:39:52  來源:環球網
  • Spring 的生命周期
    ApplicationContext那樣,配置一個自定義的後置處理bean,然後它在工程中主要是調用,你在bean中寫的environment的一個方法,或者你的bean實現了一個InitializingBean,它會第二次回調你的afterPropertiesSet方法,對bean做進一步設置,bean的二次加工完成之後,你的bean就已經建立完成了,也就是說他會根據你的bean的scope,如果是一個單列的bean,默認是單例的
  • 諾卡氏菌和維氏氣單胞菌並發引起太陽魚死亡一例
    諾卡氏菌和維氏氣單胞菌並發引起太陽魚死亡一例出處:利洋水產 作者:雷燕 水產養殖網 2016-01-28 14:48:00 廣東佛山市順德區勒流鎮一太陽魚和黃顙魚混養池塘,面積10畝,水深2米,4臺1.5kw的葉輪式增氧機(圖1)。2015年4月底存塘藍鰓太陽魚約3.8萬尾,平均規格約200g/尾;存塘黃顙魚約1.5萬尾,平均規格約200g/尾。
  • [易學springboot]對controller層進行單元測試
    對controller層的直接測試可能進行的較少。下面介紹一下在SpringBoot中進行Controller層的Rest請求測試的方法。還是使用我之前的一個rest請求第一種方法:@RunWith(SpringRunner.class)// 隨機創建出一個埠測試@SpringBootTest(classes = DemoApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class
  • 全球新冠肺炎累計確診超5300萬例 美國單日新增超18萬例
    中新社北京11月14日電 綜合消息:世界衛生組織網站最新數據顯示,截至歐洲中部時間13日16時14分(北京時間23時14分),全球確診病例較前一日增加628136例,達到52487476例;死亡病例增加9623例,達到1290653例。
  • K8s單controller多集群監測總結——client-go
    client-go的github地址:https://godoc.org/admiralty.io/multicluster-controller,client-go裡面的examples然後,GoDOC: https://godoc.org/admiralty.io/multicluster-controller
  • 【戰疫全時區】美國單日新增確診病例超25萬例 累計逾2357萬例
    【戰疫全時區】美國單日新增確診病例超25萬例 累計逾2357萬例 摘要:截至北京時間1月14日6時30分左右,美國累計確診新冠肺炎病例23571760例,累計死亡病例
  • 天津新增1例!全球多例二次感染!印度日增5萬已27天!
    目前,印度是全球單日新增確診病例最多的國家,已連續27天單日新增超過5萬例,半數印度人因疫情面臨返貧。 在亞洲,近來韓國疫情持續反彈,連續8天單日新增確診超過200例。總統文在寅稱目前疫情形勢比年初「新天地」教會聚集性感染時還要嚴峻。除高三外,首都圈中小學已改為線上授課。
  • 德國累計確診新冠肺炎超180萬例 單日死亡再超千例
    根據德國聯邦疾控機構羅伯特·科赫研究所發布的最新數據,截至當地時間1月6日0時,德國累計確診新冠肺炎病例1808647例,較前一日新增確診21237例;累計死亡36537例,較前一日新增1019例。△德國單日新增死亡病例數統計圖表 圖片來源網絡(紅線為7天均值)與此同時,過去7天德國全境新增確診新冠肺炎病例105867例,7天感染率較前一天有所下降,從134.7跌至127.3。該數值表示過去7天平均每10萬居民中有多少人新冠病毒檢測結果呈陽性。聯邦和州政府的目標是將其控制在警戒值50以下。7天感染率被認為是收緊或放鬆防疫政策的重要參考標準。
  • 單日新增破4萬例創紀錄,累計確診逼近百萬例,24...
    據法國公共衛生局更新的最新數據,截至當地時間10月22日14時,法國新冠肺炎確診病例增至999043例,24小時內新增41622例,達到自疫情暴發以來單日新增病例的最高紀錄。在10月13日到10月19日其間,法國新冠病毒核酸檢測呈陽性的比例升至14.3%。
  • 【戰疫全時區】美國單日新增確診病例超27萬例 累計逾2205萬例
    海外網1月8日電 根據Worldometer實時統計數據,截至北京時間1月8日6時30分左右,美國累計確診新冠肺炎病例22053644例,累計死亡病例373069例。與前一日6時30分數據相比,美國新增確診病例276873例,新增死亡病例4316例。(海外網 張霓)本文系版權作品,未經授權嚴禁轉載。海外視野,中國立場,瀏覽人民日報海外版官網——海外網www.haiwainet.cn或「海客」客戶端,領先一步獲取權威資訊。
  • 【戰疫全時區】美國單日新增確診病例超30萬例 累計逾2236萬例
    海外網1月9日電 根據Worldometer實時統計數據,截至北京時間1月9日6時30分左右,美國累計確診新冠肺炎病例22360623例,累計死亡病例376741例。與前一日6時30分數據相比,美國新增確診病例306979例,新增死亡病例3672例。(海外網 張敏)本文系版權作品,未經授權嚴禁轉載。海外視野,中國立場,瀏覽人民日報海外版官網——海外網www.haiwainet.cn或「海客」客戶端,領先一步獲取權威信息。
  • 美國加州單日報告585例死亡病例破紀錄
    中新社舊金山1月1日電 美國加州當地時間1日報告了585例死亡病例,創下該州單日死亡病例新高。美國約翰斯·霍普金斯大學的數據顯示,美國因新冠肺炎死亡的人數已近35萬。2020年12月是美國疫情最致命的月份,有77500多人死亡。
  • 【戰疫全時區】美國單日新增確診病例超21萬例 累計逾1448萬例
    海外網12月4日電 根據Worldometer實時統計數據,截至北京時間12月4日6時30分左右,美國累計確診新冠肺炎病例14485203例,累計死亡282101例。與前一日6時30分數據相比,美國新增確診病例214898例,新增死亡病例2767例。美國國家衛生研究院主任柯林斯2日表示,該機構仍在招募新冠病毒疫苗的實驗者。柯林斯接受CNN採訪時表示,美國政府仍然需要人們參加這些疫苗試驗。柯林斯說,即使有兩種疫苗即將獲得美國食藥局(FDA)的緊急使用許可,還有四種疫苗仍在研發中。
  • 暴增100例!緬甸疫情為何猛然復發?
    昨晚新增暴增95例確診今早新增5例確診昨晚加今早共新增100例確診,累計確診887例。疫情爆發後,我們生活物資短缺,雖然不知道這個是不是真的,但還是去了現場。我們到了才發現不是真的。現場大概聚集著200多人。