【问题标题】:Are Spring Controllers Thread-SafeSpring 控制器是线程安全的吗
【发布时间】:2012-12-18 05:16:29
【问题描述】:

我遇到了这个控制器示例,想知道它是否是线程安全的?我特别想知道 gson 实例变量。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.google.gson.Gson;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class TestController {

    private final Gson gson = new Gson();

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public void test(HttpServletResponse res, HttpServletRequest req) throws IOException {
        HashMap<String, String> hm = new HashMap();
        res.getWriter().print(gson.toJson(results));
        res.getWriter().close();
    }
}

【问题讨论】:

标签: java spring


【解决方案1】:

要回答标题“Spring 控制器是否线程安全”中的问题,Spring 控制器是单例的,因此它们应该以线程安全的方式实现,但您需要确保您的实现实际上是线程安全的。

在您发布的代码中应该没问题,因为正如其他人指出的那样,GSON 是线程安全的。

【讨论】:

  • 假设 Servlet 的所有线程安全规则,也适用于 Spring Controller,理解正确吗?
【解决方案2】:

假设这个控制器被创建为一个普通的 Spring“单例”bean,答案是

您可以将控制器创建为prototype bean,在这种情况下,将为每个请求创建一个新实例。如果你想这样做,一个更好的主意是将你的 bean 的范围定义为request

但是,我质疑 any 控制器对象具有成员变量的原因,除了可能错误地确定 bean 的范围。这表明控制器正在尝试做太多的工作,并且应该将其中一些工作卸载到服务或帮助程序类。 MVC 控制器应该做的唯一事情是将请求数据传递到服务层,并检索要由视图显示的数据。

【讨论】:

  • @Boris - 足够详细了吗?我觉得在提供替代方案之前阻止 OP 做一些愚蠢的事情很重要。
  • OP 说得很清楚,问题是关于 GSON 实例的线程安全I am wondering specifically about the gson instance variable.
  • @Boris - 好的。但我想知道为什么他/她没有提出像“Gson 线程安全”这样的标题?
  • 提出问题很难,选择正确的标题很难。附言使对象受线程限制(更改范围也不会自动使对象受线程限制)不会使其类成为线程安全的。
【解决方案3】:

Gson 绝对是线程安全的,并且早在 2008 年就以这种方式制作,所以只要您的版本是发布的,那么它应该没问题。我发现您的代码没有线程安全问题。虽然我会将Gson 的实例设为静态。

【讨论】:

  • Gson 可能是线程安全的,但是将成员变量放入控制器是一个不好的习惯。
  • 这真的取决于,例如您通常会看到诸如服务实现之类的东西作为成员变量被注入......但是,对于Gson,我会专门将其设为静态,只是原则上的问题。
  • 避免使用成员变量就像骑三轮车害怕摔倒而不是学习如何骑乘和道路规定-你不会摔倒,但它不能给你一个错误安全感。
【解决方案4】:

就像 servlets 控制器请求处理程序方法也不是线程安全的。即对/test 的多次请求可能会使许多线程执行测试方法。

在您的示例中,您不必担心线程安全,因为 gson.toJson(results) 是 gson 上的唯一操作,并且似乎不会改变该对象的状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2015-07-22
    • 2013-04-04
    • 1970-01-01
    • 2011-10-08
    • 2016-05-01
    • 1970-01-01
    相关资源
    最近更新 更多