【问题标题】:private method inside spring mvc controller is thread safespring mvc控制器内部的私有方法是线程安全的
【发布时间】:2013-10-03 19:58:28
【问题描述】:

据我了解,spring mvc 控制器默认是线程安全的(如 servlet)。但我只想知道控制器内的任何私有辅助方法都是线程安全的吗?

我在控制器类中有两个映射,例如:/test 和 test/success。每次用户调用此 url 时,我都想使用服务方法(两个不同的调用)检查数据库中的用户状态和激活时间。所以我决定创建一个私有助手方法来检查状态。 那么有谁知道我的私有方法是线程安全的吗?

【问题讨论】:

  • 不,你在这两点上完全错了:spring mvc 控制器默认是线程安全的(就像 servlet) 可见性与线程安全有什么关系?
  • mvc 控制器默认为单例,当请求到来时会像 servlet 生命周期一样调用新线程?
  • 那么该线程的安全性如何?
  • 我的意思是映射方法中的任何局部变量都是线程安全的。不是实例变量。
  • 好吧,那是完全不同的。这并不能使类线程本身安全。而private与线程安全无关。

标签: java multithreading spring spring-mvc


【解决方案1】:

所有请求都由控制器的一个实例处理(单例,因为它是一个弹簧管理的 bean)。因此,您需要确保不存储与一个请求相关的任何状态(在字段中)。

所以:

@Controller
@RequestMapping("/foo")
public class Foo {
    @Autowired
    private Something something;

    @RequestMapping("/list")
    public String foo() {
       something.someMethod();
       bar();
       return "view"
    }

    private void bar() {
        // something
    }
}

没问题,但是:

@Controller
@RequestMapping("/foo")
public class Foo {

    private User theUser; // problem is ALL request share this field

    @RequestMapping("/foo/{userId}")
    public String foo(@PathVariable final Integer userId) {
       if (theUser.getId().equals(userId)) {
           // something
       } else {
           theUser = ...
       }
       return "view"
    }
}

不是。

注意:未经测试(仅在此处输入,因此它甚至会伤害您的编译器)

【讨论】:

  • 是的。我应该避免私有方法。所以我认为我需要调用服务方法或在两个映射方法中编写相同的逻辑?
  • 这正是我问的......我决定像第一个例子一样做。如果多个用户同时调用同一个 url,那是线程安全的吗?
  • 是的,但最佳实践建议不要在控制器中放置任何逻辑
  • 对不起,我迷路了,我的示例代码是两个相反的东西,你应该编辑你的问题并添加你的代码。
  • 是的,您只是“使用”它,而不是分配给它。由于它是由 spring 自动装配的,它是在 bean 实例化/构造时完成的
猜你喜欢
  • 2015-02-05
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
相关资源
最近更新 更多