gpt4 book ai didi

java - Spring Rest Web 请求范围

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:18:31 24 4
gpt4 key购买 nike

我正在编写一个 Spring REST 类型的接口(interface)到一个数据库,它将检索各种资源的用户特定结果。

为了保留用户,我有一个名为 CurrentUser 的 spring @Component 注释 bean 作为临时措施。

@Component
public class CurrentUser {

@Autowired
private UserDAO userDAO;

private String userId;
private String email;
private String notes;

public String getUserId() {
return userId;
}

public void setUserId(String userId) throws ApiException {
User user = userDAO.getUser(userId) // Database call to
if (!user.isValid()) {
throw ApiException(...) // The exception would crash back to the user as a error in the response
}

// Valud user so set these aspects.
this.userId = user.userId;
this.email = user.email;
}
}

每次使用以下拦截器调用 API 中的任何方法时,都会在 Spring 拦截器中初始化此对象。

public class AuthenticationInterceptor extends HandlerInterceptorAdapter {
@Autowired
private CurrentUser user;

@Autowired
private RequestParameters requestParameters;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ApiException {
user.setUserId(StringUtils.defaultString(request.getParameter("userId"), "defaultUser"));
return true;
}
}

这只是一个占位符,用于在添加适当的身份验证之前识别用户。

我对 Spring 比较陌生,写这篇文章的原因是为了增加我在这种情况下对 Spring 的线程安全方面的理解

我最近发现 Spring 并不是自动线程安全的,我可能需要更多地考虑作用域。

我想了解的是:

  1. 对于上述设置,是否存在 1000 多个并发请求可能会相互干扰和覆盖的危险?例如对一个用户的请求可能会被另一个来自单独 http 请求的用户覆盖,从而导致请求者接收到错误的数据。

  2. 解决此问题的最佳方法是什么。 (即使它将被替换,我也以类似的方式实例化了其他对象)我正在查看的选项(如果这是一个问题)正在设置原型(prototype)范围,或者直接附加到请求/ session 而不是允许它们自己的 Autowiring 对象。

任何人都可以给我的任何信息都将不胜感激,因为我喜欢一开始就做对(呃),而不是稍后处理错误的假设。

最佳答案

答案 1:是的,而且您不需要 1000 个请求就会惹上麻烦。并行 2 个请求就足够了。

答案 2:这里的主要问题是范围界定之一:

Spring 托管 bean 的默认作用域是 Singleton。这意味着每个应用程序只存在一个 CurrentUser 实例。

这显然不是您想要的。 (因为这里存在严重的安全问题,每个应用程序只有一个 CurrentUser 实例)。

简单答案:

我可能会使用 Spring Security ;-)

更简单的答案:

如果那不是一个选项:

  • 使用 Filter 而不是 HandlerInterceptor(更直接地控制清理)

  • 创建一个Thread Local来存储用户(并在Filter中使用一个finally来清理)并在Filter中设置

  • 创建一个请求范围的服务(使用@ScopedProxy,以便能够将其连接到单例中),将 ThreadLocal 作为 UserService 进行访问(您需要一个接口(interface)来使其轻松工作)

  • 在您需要的地方 Autowiring 此 UserService

由于根据规范,Servlet 环境中的每个请求都绑定(bind)到一个线程,并且线程局部变量本质上是线程安全的,因此您是完全线程安全的,并且可以很好地扩展。作用域代理的开销是最小的。

(这只是一个选项,其他选项可以显式地使用请求范围或以稍微更优雅的方式使用方面。但是,这是一种相当简单的方法并且可以完成工作。对于更复杂的需求,我会严重建议研究 Spring Security)。

关于java - Spring Rest Web 请求范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31786298/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com