spring mvc controller 是不是单例

2024-12-02 02:49:17
推荐回答(1个)
回答1:

我们知道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"),将其设置为多例模式