Spring 组件类必须是线程安全的 [英] Must Spring component classes be thread-safe

查看:32
本文介绍了Spring 组件类必须是线程安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您使用 Spring,您的组件类(@Controller@Service@Repository)是否必须是线程安全的?还是 Spring 以线程安全的方式使用它们,这样您就不必担心线程安全?

If you use Spring, must your component classes (@Controller, @Service, @Repository) be thread safe? Or does Spring use them in a thread-safe manner so you don't have to worry about thread safety?

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

That is, if I have a @RequestMapping method in my @Controller, could that method be called simultaneously for the same controller object by more than one thread?

(这已经之前询问过,但是没有这样回答).

(This has sort-of been asked before, but not answered as such).

推荐答案

Given

@Controller
public class MyController {
    @RequestMapping(value = "/index")
    public String respond() {
        return "index";
    }
}

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

Spring will create an instance of MyController. This is because Spring parses your configuration, <mvc:annotation-driven>, sees @Controller (which is like @Component) and instantiates the annotated class. Because it sees @RequestMapping as well, it generates a HandlerMapping for it, see the docs here.

DispatcherServlet收到的任何HTTP请求都会通过之前注册的HandlerMapping分派到这个控制器实例,通过java反射调用respond()在那个实例上.

Any HTTP requests the DispatcherServlet receives will be dispatched to this controller instance through the HandlerMapping registered before, calling respond() through java reflection on that instance.

如果你有像

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

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

count would be a hazard, because it might be modified by many threads and changes to it might be lost.

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

You need to understand how Servlet containers work. The container instantiates one instance of your Spring MVC DispatcherServlet. The container also manages a pool of Threads which it uses to respond to connections, ie. HTTP requests. When such a request arrives, the container picks a Thread from the pool and, within that Thread, executes the service() method on the DispatcherServlet which dispatches to the correct @Controller instance that Spring registered for you (from your configuration).

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

So YES, Spring MVC classes must be thread safe. You can do this by playing with different scopes for your class instance fields or just having local variables instead. Failing that, you'll need to add appropriate synchronization around critical sections in your code.

这篇关于Spring 组件类必须是线程安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆