春天控制器 - 线程安全和存储资源(Spring controllers - thread safe

2019-07-31 03:58发布

我有一个关于Spring MVC和线程安全问题。

我们正在开发能够将存储在Tomcat Web应用程序。 如果我理解正确,Tomcat的创建每个请求的线程,它具有一定的线程池。 现在,调度员的servlet请求之间共享,可能是线程安全的。

但是,当我创建控制器是这样的:

@Controller
@RequestMapping("/manage")
public class QuestionManagementController {

他有Singleton范围,所以,相同的控制器所使用的每一个来自每一个用户的请求。

我想知道如何这个问题通常是解决:

1:被控制器使用创建Session范围? (但我认为可能还会有问题,如果一个用户快速地做一些事情,可能会导致比赛的控制条件下)。

2:控制器作用域确定为request

3:创建不能以只读模式在共享类级别的变量,或让他们无状态控制器

或者也许有是解决此类问题的一些更好的“最佳实践”。

我问这个问题,因为现在我们有他们的Singleton范围的,且有一个问题,即在大多数的方法,我们在数据库中查询用户,我们不能在类级别变量存储这些信息,因为范围。 我们可以尝试使用一些线程安全的集合,但以后可能还有其他的资源需要同步访问。

Answer 1:

一个很多参数可以被添加到控制器方法,如请求,会话,校长等,以避免您的问题。

通常有一个3层架构:

  • @Controller (他们委托给服务)
  • @Service (他们使用的DAO或库的工作)
  • @Repository (或DAO的,他们做的DB访问)

所以,这取决于你在DB查询,我会建议有一个服务,由Spring与高速缓存注入,如果击中DB是昂贵的,每次你需要的东西,从数据库调用服务(即存储在控制器无类级)

简单例子,假设我们是落后弹簧安全,一切都需要一个完全登录的用户。 我们有一个userData表,其中的关键是用户登录,我们有一个URL /data获得一个页面显示我的用户数据:

@Controller
@RequestMapping("/data")
public class UserDataController
{
    @Autowired
    private UserService userService;

    @RequestMapping(value = "", method = RequestMethod.GET)
    public ModelAndView data(final Principal principal) {
        Assert.notNull(principal); // throw if assertion fails
        Assert.hasText(principal.getName());

        final UserData userData = this.userService.findByUserName(principal.getName());
        Assert.notNull(userData, "userData not found");

        return new ModelAndView("userData", "userData", userData);
    }
}

@Service("userService")
public class userService 
{
    private static final String USERDATA_CACHE = "com.acme.foo.UserData";

    @Autowired
    private UserDataRepository userDataRepository;

    @Cacheable(USERDATA_CACHE)
    public UserData findByUserName(final String userName) {
        return this.userDataRepository.findByUserName(userName);
    }
}

@Repository
public class UserDataRepository
{
    // or use spring-data-jpa

    public UserData findByUserName(final String userName) {
        // query table userData and create an UserData from results.
    }
}

这里我用的本金和弹簧确保这是当前用户之一。

参考文献:

  • @Cachable
  • 又见初始化独身Spring框架3 MVC

注知道这个答案完全对您的问题



文章来源: Spring controllers - thread safety and storing resources