有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我将使用thisdocker映像部署一个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]

这会让我有点担心并发会话,问题是如何修复它


共 (3) 个答案

  1. # 1 楼答案

    您有一个GreetingResource类(singleton)实例来服务您的所有请求。它们将共享您在类中定义的实例变量,如f.x.dummyList

    如果您需要包含范围请求的内容,您可以使用范围请求(如f.x)注入bean

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

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

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

    如果这不能解决您的问题,那么如果您能给我们一些关于为什么需要这个dummyList变量的信息,这将是非常有用的

  2. # 2 楼答案

    这就是为什么:

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

    根据经验:Never keep instance variables在服务类中。尽可能使用DTO和值对象来维护状态。在构建面向服务的体系结构方面,您有一个很大的禁忌

    具体而言,对于此场景,Quarkus将服务类(GreetingResources)的作用域默认为singleton作用域,这意味着一个实例将用于服务所有请求

    您可以通过在配置中配置^{}属性来更改此行为

  3. # 3 楼答案

    如果希望在每次方法调用后都有一个干净的响应,可以尝试在方法内声明arraylist

    @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();
    }