Spring组件类必须是线程安全的吗

ppcbkaq5  于 2023-05-05  发布在  Spring
关注(0)|答案(4)|浏览(158)

如果你使用Spring,你的组件类(@Controller@Service@Repository)必须是线程安全的吗?或者Spring以线程安全的方式使用它们,所以您不必担心线程安全性?
也就是说,如果我在@Controller中有一个@RequestMapping方法,那么这个方法可以被多个线程同时调用吗?
(This有sort-of been asked before,但没有这样回答)。

vmpqdwk3

vmpqdwk31#

鉴于

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

Spring将创建MyController的示例。这是因为Spring会解析您的配置<mvc:annotation-driven>,看到@Controller(类似于@Component)并示例化带注解的类。因为它也能看到@RequestMapping,所以它会为它生成一个HandlerMapping,请参阅这里的文档。
DispatcherServlet接收到的任何HTTP请求都将通过之前注册的HandlerMapping发送到这个控制器示例,并通过该示例上的java反射调用respond()
如果您有示例字段,如

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

count将是一个危险,因为它可能被许多线程修改,对它的更改可能会丢失。
您需要了解Servlet容器是如何工作的。容器示例化Spring MVC DispatcherServlet的一个示例。容器还管理一个线程池,用于响应连接。HTTP请求。当这样的请求到达时,容器从池中选择一个Thread,并在该Thread中,在DispatcherServlet上执行service()方法,该方法将分派到Spring为您注册的正确@Controller示例(从您的配置)。
所以是的,Spring MVC类必须是线程安全的。你可以通过为你的类示例字段使用不同的作用域或者只使用局部变量来实现这一点。如果做不到这一点,您将需要在代码中的关键部分周围添加适当的同步。

bvhaajcl

bvhaajcl2#

是的,当然。
最好是无状态的,这使得它们默认是线程安全的。如果没有共享的、可变的状态,就没有问题。

kx1ctssn

kx1ctssn3#

默认情况下,控制器是单例的,因此必须是线程安全的。但是,您可以将控制器配置为请求或会话范围,即:

@Controller
@Scope("session")
public class MyController {

    ...
}

具有 session scope 的控制器有助于管理会话状态。在Using Sessions in Spring-MVC (including "scoped-proxies")How to get Session Object In Spring MVC中可以找到对不同模式的良好描述。所呈现的一些模式需要 * 请求范围 *。
如果您的数据无法为每个请求计算多个值,则请求范围也很有用。

f4t66c6m

f4t66c6m4#

Spring组件和其他类必须是线程安全的,如果它可以被多个线程并发使用。Spring组件默认是单例的,可以从不同的线程调用。从这个Angular 来看,它的STATE应该是线程安全的。另一方面,单例Springbean通常在线程池中的线程的调用堆栈中服务请求。通常,Spring组件具有字段,其值是注入的接口或属性。唯一需要注意安全性的是状态对象保存在bean中的情况。通常,由于服务器是负载平衡的,并且状态保存在缓存或数据库中,因此不使用它。因此,Singleton bean应该被用作一组函数,它将数据作为相关方法的参数进行传输,并且它的字段不应该保存业务数据,而只是注入的bean,它为调用过程提供服务。Spring的控制器就是一个例子。它的方法由Tomcat的线程调用,控制器方法Map的方式,所有的调用堆栈都在一个线程中完成。控制器的方法调用DAO方法并在同一个线程中返回结果。Session通常在会话之间持久化,这由Spring处理。因此,除了极少数情况外,没有必要考虑线程安全性。

相关问题