springmvc中的controller是單例的


 

 我們知道Spring MVC是多線程單實例的MVC框架,就是說,對於同一個Controller,只會生成一個實例來處理所有的請求,因此bean實例只會實例化一次,並被存放在工廠中,以供其他請求使用

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

單例的原因有二:

1、為了性能。

2、不需要多例。

 

1、這個不用廢話了,單例不用每次都new,當然快了。

2、不需要實例會讓很多人迷惑,因為spring mvc官方也沒明確說不可以多例。

  我這里說不需要的原因是看開發者怎么用了,如果你給controller中定義很多的屬性,那么單例肯定會出現競爭訪問了。

  因此,只要controller中不定義屬性,那么單例完全是安全的。下面給個例子說明下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package  com.lavasoft.demo.web.controller.lsh.ch5;
import  org.springframework.context.annotation.Scope;
import  org.springframework.stereotype.Controller;
import  org.springframework.ui.ModelMap;
import  org.springframework.web.bind.annotation.RequestMapping;
/**
  * Created by Administrator on 14-4-9.
  *
  * @author leizhimin 14-4-9 上午10:55
  */
@Controller
@RequestMapping( "/demo/lsh/ch5" )
@Scope( "prototype" )
public  class  MultViewController {
     private  static  int  st =  0 ;       //靜態的
     private  int  index =  0 ;           //非靜態
     @RequestMapping( "/show" )
     public  String  toShow(ModelMap model) {
         User user =  new  User();
         user.setUserName( "testuname" );
         user.setAge( "23" );
         model.put( "user" , user);
         return  "/lsh/ch5/show" ;
     }
     @RequestMapping( "/test" )
     public  String  test() {
         System.out.println(st++ +  " | "  + index++);
         return  "/lsh/ch5/test" ;
     }
}

 

 

0 | 0

1 | 1

2 | 2

3 | 3

4 | 4

 

改為單例的:

0 | 0

1 | 0

2 | 0

3 | 0

4 | 0

 

從此可見,單例是不安全的,會導致屬性重復使用。

 

最佳實踐:

1、不要在controller中定義成員變量。

2、萬一必須要定義一個非靜態成員變量時候,則通過注解@Scope("prototype"),將其設置為多例模式


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM