给定
@Controllerpublic class MyController { @RequestMapping(value = "/index") public String respond() { return "index"; }}Spring将创建的实例
MyController。这是因为Spring解析了您的配置,
<mvc:annotation-driven>sees
@Controller(类似于
@Component)并实例化了带注释的类。因为它也可以看到
@RequestMapping,所以会为其生成一个
HandlerMapping,请参见此处的文档。
DispatcherServlet接收到的所有HTTP请求都将通过
HandlerMapping之前注册的对象调度到该控制器实例,并
respond()通过对该实例的java反射进行调用。
如果您有类似的实例字段
@Controllerpublic class MyController { private int count = 0; @RequestMapping(value = "/index") public String respond() { count++; return "index"; }}count这将是一种危险,因为它可能会被许多线程修改,并且对其所做的更改可能会丢失。
您需要了解Servlet容器的工作方式。该容器实例化了Spring
MVC的一个实例
DispatcherServlet。容器还管理线程池,用于响应连接,即。HTTP请求。当这样的请求到达时,容器从池中选择一个线程,并在该线程内执行上的
service()方法,该方法将
DispatcherServlet分派到
@ControllerSpring为您注册的正确实例(根据您的配置)。
所以是的,Spring
MVC类必须是线程安全的。您可以通过为类实例字段使用不同的作用域或仅使用局部变量来实现。否则,您需要在代码中的关键部分周围添加适当的同步。



