【问题标题】:How can I create variables that are accessible throughout the entire application, but simultaneously request specific?如何创建可在整个应用程序中访问但同时请求特定的变量?
【发布时间】:2020-03-18 13:51:34
【问题描述】:

我有一个 springboot 微服务,我想为此增强它的日志记录功能。每次我向该服务发送 HTTP 请求时,都会有一些我希望在整个应用程序中访问的信息。例如,如果我要在请求正文中发送一个名称,我可能希望将该名称记录到应用程序的几个不同类中。如果不在每个方法或类中传播该数据,我该如何做到这一点?我想要某种全局可访问的变量,但由于该服务有多个线程,我不希望有可能访问我存储的另一个线程的请求信息。

一个示例请求正文可能是这样的:

{
  "name": "Silly Willy",
  "birthday": "2020-02-02"
}

在我的应用程序中,我想创建一个变量来保存该名称。我希望它是线程安全的、特定于请求的,但在请求期间可以在整个应用程序中访问。类似于静态变量的东西:

//In the class
public class Object {
  private static final String name;

  public Object(String name) {
    Object.name = name;
  }

  public static String getName() {
    return name;
  }
}
//In controller
Object obj = new Object(request.getName());

我知道字符串是不可变的,静态变量不是线程安全的,但我不完全确定我在寻找什么。有人建议使用 bean,并将范围设置为 request,但我不确定这会是什么样子,或者是否可以使用构造函数方法(假设我要创建一个类来存储这些应用程序可访问变量)。

理想情况下,我希望能够在请求进来时创建一个对象或在控制器中实例化一些东西,这样我就可以使用这个对象来促进我的日志记录:

log.info("{}", obj.getName());

【问题讨论】:

  • 你可以把它存储在一个HttpSession中
  • 假设您使用 slf4j 将其存储在 MDC 中,或者在请求期间使用 ThreadLocal 将其存储。请注意在请求完成后清除它(这适用于 MDC 作为 ThreadLocal!
  • 我实际上也研究了 ThreadLocal,我认为这可能是最有意义的!现在将对其进行更多研究

标签: java spring spring-boot logging httprequest


【解决方案1】:

我假设您在 Spring Boot 应用程序中,因为您这样标记了您的问题。

然后像这样简单地创建一个请求范围的 bean:

@Bean
@RequestScope
public MyBean myBean () {
    return new MyBean();
}

您可以将其注入到您想要的任何其他 bean 中,并将绑定到每个传入请求。

您的 Bean 本身甚至可以像这样自动装配当前的 HttpServletRequest 或 Response:

public class MyBean {

  @Autowired
  private HttpServletRequest request;

// do something with the request and present it in a getter..

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    相关资源
    最近更新 更多