一尘不染

Spring MVC类必须是线程安全的

spring-mvc

如果你使用Spring MVC的,必须在组件类(@Controller@Service@Repository)是线程安全的吗?

也就是说,如果我中有一个@RequestMapping方法@Controller,是否可以通过多个线程同时针对同一控制器对象调用该方法?


阅读 396

收藏
2020-06-01

共1个答案

一尘不染

给定

@Controller
public 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反射进行调用。

如果您有类似的实例字段

@Controller
public 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类必须是线程安全的。您可以通过为类实例字段使用不同的作用域或仅使用局部变量来实现。否则,您需要在代码中的关键部分周围添加适当的同步。

2020-06-01