问题描述
我将使用 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]
解决方法
这是为什么:
private final List<String> dummyList = new ArrayList<>();
根据经验:Never keep instance variables 在服务类中。尽可能使用 DTO 和值对象来维护状态。在构建面向服务的架构方面,您所拥有的东西是一个很大的禁忌。
具体来说,对于这种情况,Quarkus 将服务类 (GreetingResources
) 的范围默认为单例范围,这意味着将使用单个实例来处理所有请求。
您可以通过在配置中配置 quarkus.resteasy.singleton-resources
属性来更改此行为。
如果你想在每次方法调用后都有一个干净的响应,你可以尝试在方法内部声明数组列表。
@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 类(单例)实例处理您的所有请求。他们将分享你定义了实例变量在类像F.X. dummyList
。
如果你需要具有范围请求的东西,你可以注入一个具有范围请求的 bean,比如 f.x。
@Bean
@RequestScope
public HelloMessageGenerator requestScopedBean() {
return new HelloMessageGenerator();
}
此实例是来自https://www.baeldung.com/spring-bean-scopes
您可能要移动dummyList
您的hello
方法内是否会为你工作。
如果这不能解决您的问题,如果您能向我们提供一些有关您为何需要此 dummyList
变量的信息,将会很有帮助。