我知道具有相同内容的两个请求使用不同的线程。而且我认为不同的线程将使用@Controller注释创建不同的实例。但是当我运行下面的代码时,我发现我的想法是错误的。
测试代码:
@Controller
@RequestMapping("test")
public class TestADEDSAController {
private String string = "";
@RequestMapping("controllerTest")
@ResponseBody()
public String controllerTest(@RequestParam String string) {
return this.string += string;
}
}
第一次响应内容如下:
test
第二次是这样的:
testtest
似乎JVM中只有一个Test实例。
我想知道JVM中是否始终只有一个@Controller实例是真的吗?另外,在哪里可以找到有关此过程的详细介绍?
答案 0 :(得分:4)
默认情况下,Spring中的所有bean均创建为singleton
(每个IOC容器一个)。
这是javadoc
(默认值)在每个Spring IoC容器中将单个bean定义的作用域限定为单个对象实例。
答案 1 :(得分:3)
默认情况下,Spring创建一个bean的单个共享实例。 Bean范围默认为singleton
。如果需要在每个请求上创建一个新实例,则应将bean范围定义为prototype
。这可以通过用@Scope("prototype")
注释类或通过在spring配置xml中定义范围来实现,如下所示:
<bean id="controllerId" class="com.package.name.TestADEDSAController" scope="prototype"/>
请通过https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html来在春季更好地了解bean范围。
答案 2 :(得分:0)
否,默认情况下,对象是单例。这意味着您的对象必须是线程安全的。 因此,在控制器中使用不安全的值(例如字符串)是不明智的做法(常量除外)。
如果两个线程同时进入那里,您的字段可能会损坏。
答案 3 :(得分:0)
默认作用域是“单个”,因此,如果您需要Spring每次创建一个新实例,则除了@Controller注释外,还可以使用@Scope(“ prototype”)注释。还有其他Web感知范围,例如请求,会话和全局会话。阅读here中的示例。