Java 变量值在响应请求后保留在内存中

Java variable values persist in memory after responding to a request

我将使用 this docker 映像部署 Java 应用程序。我试图消除即使在生成响应后变量的值仍然存在的问题。我的假设是每个请求都有一个隔离的环境,但我不确定是否正确。

例如,下面给定的代码块会将给定的 URL 参数添加到虚拟列表中。

@Path("/hello")
public class GreetingResource {

    private final List<String> dummyList = new ArrayList<>();

    @GET
    @Path("/{param}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response hello(@PathParam("param") String param) throws InterruptedException {
        dummyList.add(param);
        
        return Response.ok(dummyList.toString()).build();
    }
}

如果像这样卷曲端点两次:

/hello/client1
/hello/client2

我的期望是收到:

[client1]
[client2]

但我实际得到的是:

[client1]
[client1, client2]

这会让我有点担心并发会话,问题是我该如何解决它。

如果你想在每次方法调用后都有一个干净的响应,你可以尝试在方法中声明数组列表。

@GET
@Path("/{param}")
@Produces(MediaType.APPLICATION_JSON)
public Response hello(@PathParam("param") String param) throws InterruptedException {
    List<String> dummyList = new ArrayList<>();
    dummyList.add(param);
    
    return Response.ok(dummyList.toString()).build();
}

您有一个 GreetingResource class(单例)实例来处理您的所有请求。他们将共享您在 class 中定义的实例变量,例如 f.x。 dummyList.

如果你需要范围请求的东西,你可以注入一个范围请求的bean,比如f.x。

@Bean
@RequestScope
public HelloMessageGenerator requestScopedBean() {
    return new HelloMessageGenerator();
}

这个例子来自https://www.baeldung.com/spring-bean-scopes.

您可能希望将 dummyList 移动到您的 hello 方法中,如果这对您有用的话。

如果这不能解决您的问题,如果您能向我们提供一些有关为什么需要此 dummyList 变量的信息,将会很有帮助。

这就是为什么:

private final List<String> dummyList = new ArrayList<>();

根据经验:Never keep instance variables 服役 classes。尽可能使用 DTO 和值对象来维护状态。你所拥有的是构建面向服务的架构的一大禁忌。

对于这种情况,Quarkus 默认服务范围 class ( GreetingResources) 为单例范围,这意味着将使用单个实例来服务所有请求。

您可以通过在配置中配置 quarkus.resteasy.singleton-resources 属性 来更改此行为。