具有@Controller注释的Class是否是单个对象?

时间:2018-07-26 11:21:19

标签: java spring spring-mvc tomcat io

我知道具有相同内容的两个请求使用不同的线程。而且我认为不同的线程将使用@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实例是真的吗?另外,在哪里可以找到有关此过程的详细介绍?

4 个答案:

答案 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中的示例。