spring mvc 的Controller類默認Scope是單例(singleton)的

使用Spring MVC有一段時間了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 說是因爲線程安全問題,對於Spring MVC中bean默認都是(singleton)單例的,那麼用@Controller註解標籤注入的Controller類是單例實現的?

測試結果發現spring3中的controller默認是單例的,若是某個controller中有一個私有的變量i,所有請求到同一個controller時,使用的i變量是共用的,即若是某個請求中修改了這個變量a,則,在別的請求中能夠讀到這個修改的內容。 若是在@Controller之前增加@Scope(“prototype”),就可以改變單例模式爲多例模式

以下是測試步驟,代碼與結果.

1. 如果是單例類型類的,那麼在Controller類中的類變量應該是共享的,如果不共享,就說明Controller類不是單例。以下是測試代碼:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ExampleAction {
    private int singletonInt=1;
     @RequestMapping(value = "/test")
     @ResponseBody
     public String singleton(HttpServletRequest request,
             HttpServletResponse response) throws Exception {
         String data=request.getParameter("data");
         if(data!=null&&data.length()>0){
             try{
              int paramInt= Integer.parseInt(data);
             singletonInt = singletonInt + paramInt;
             }
             catch(Exception ex){
                 singletonInt+=10;
             }
         }else{
             singletonInt+=1000;
         }
         return String.valueOf(singletonInt);
    }
}

分別三次請求: http://localhost:8080/example/test.do?data=15

得到的返回結果如下。

第一次: singletonInt=15

第二次: singletonInt=30

第三次: singletonInt=45

從以上結果可以得知,singletonInt的狀態是共享的,因此Controller是單例的。

2. 如果Controller類是單例,那麼多個線程請求同一個Controller類中的同一個方法,線程是否會堵塞

@RequestMapping(value = "/sleepdata")
@ResponseBody
public String switcher(HttpServletRequest request
     , HttpServletResponse response)
           throws Exception {
  String sleep = request.getParameter("sleep");
  if (sleep.equals("on")) {
      Thread.currentThread().sleep(100000);
       return "sleep on";
   } else {
       return sleep;
  }

驗證方法:分別發送兩個請求,

第一個請求:http://localhost:8080/coreplat/sleepdata.do?sleep=on

第二個請求:http://localhost:8080/coreplat/sleepdata.do?sleep=test

驗證結果:第一個請求發出去以後,本地服務器等待100s,然後返回結果”sleep on”,在本地服務器等待的者100s當中,發送第二個請求,直接返回結果”test”。說明之間的線程是不互相影響的。

參考來源 spring mvc 的Controller類是單例(singleton)的嗎?.

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