弹簧组件类必须是线程安全的
如果使用 Spring,组件类 (, 、 ) 必须是线程安全的吗?或者Spring是否以线程安全的方式使用它们,因此您不必担心线程安全?@Controller
@Service
@Repository
也就是说,如果我在我的 中有一个方法,是否可以由多个线程同时为同一控制器对象调用该方法?@RequestMapping
@Controller
(这个问题以前问过,但没有这样回答)。
如果使用 Spring,组件类 (, 、 ) 必须是线程安全的吗?或者Spring是否以线程安全的方式使用它们,因此您不必担心线程安全?@Controller
@Service
@Repository
也就是说,如果我在我的 中有一个方法,是否可以由多个线程同时为同一控制器对象调用该方法?@RequestMapping
@Controller
(这个问题以前问过,但没有这样回答)。
鉴于
@Controller
public class MyController {
@RequestMapping(value = "/index")
public String respond() {
return "index";
}
}
Spring 将创建一个 .这是因为 Spring 解析您的配置,,看到(类似于 )并实例化带注释的类。因为它也看到,它为它生成一个,请参阅此处的文档。MyController
<mvc:annotation-driven>
@Controller
@Component
@RequestMapping
HandlerMapping
接收的任何HTTP请求都将通过之前注册的实例调度到此控制器实例,并通过该实例上的java反射进行调用。DispatcherServlet
HandlerMapping
respond()
如果您有实例字段,例如
@Controller
public class MyController {
private int count = 0;
@RequestMapping(value = "/index")
public String respond() {
count++;
return "index";
}
}
count
这将是一个危险,因为它可能会被许多线程修改,并且对它的更改可能会丢失。
您需要了解 Servlet 容器的工作原理。容器实例化了 Spring MVC 的一个实例。容器还管理一个线程池,用于响应连接,即。HTTP 请求。当这样的请求到达时,容器从池中选取一个 Thread,并在该 Thread 中执行该方法,该方法调度到 Spring 为您注册的正确实例(从您的配置中)。DispatcherServlet
service()
DispatcherServlet
@Controller
所以是的,Spring MVC类必须是线程安全的。为此,您可以为类实例字段使用不同的作用域,或者只使用局部变量。如果做不到这一点,则需要在代码中的关键部分周围添加适当的同步。
是的,当然。
最好是无状态的,这使得它们在默认情况下是线程安全的。如果没有共享的可变状态,则没有问题。