必须Spring MVC类是线程安全的

Rae*_*ald 28 java spring-mvc thread-safety

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

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

(之前有人问过这种情况,但没有这样回答).

Sot*_*lis 49

特定

@Controller
public class MyController {
    @RequestMapping(value = "/index")
    public String respond() {
        return "index";
    }
}
Run Code Online (Sandbox Code Playgroud)

Spring将创建一个实例MyController.这是因为Spring解析了你的配置,<mvc:annotation-driven>看到了@Controller(就像@Component)并实例化了带注释的类.因为它也可以看到@RequestMapping,它会HandlerMapping为它生成一个,请参阅此处文档.

任何HTTP请求DispatcherServlet都会通过HandlerMapping之前注册的调度将调度发送到此控制器实例,respond()通过该实例上的java反射调用.

如果你有像实例字段

@Controller
public class MyController {
    private int count = 0;
    @RequestMapping(value = "/index")
    public String respond() {
        count++;
        return "index";
    }
}
Run Code Online (Sandbox Code Playgroud)

count 会有危险,因为它可能会被许多线程修改,并且可能会丢失对它的更改.

您需要了解Servlet容器的工作方式.容器实例化Spring MVC的一个实例DispatcherServlet.容器还管理一个用于响应连接的线程池,即.HTTP请求.当这样的请求到达时,容器从池中选择一个Thread,并在该Thread内执行派生到Spring为您注册的正确实例的service()方法(来自您的配置).DispatcherServlet@Controller

所以,是的,Spring MVC类必须是线程安全的.您可以通过为类实例字段播放不同的范围或仅使用局部变量来实现此目的.如果做不到这一点,您需要在代码中的关键部分周围添加适当的同步.