spring controller 單例如何保證併發安全

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

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

package com.riemann.springbootdemo.controller;
 
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
 
@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

 

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章