【问题标题】:Is it able to inject RequestScope bean into Singleton bean using Constructor Injection in Spring?是否能够在 Spring 中使用构造函数注入将 RequestScope bean 注入 Singleton bean?
【发布时间】:2021-06-14 01:13:45
【问题描述】:

据我测试,它正在工作。但我不明白它为什么以及如何工作。(我也不确定在生产中使用它是否安全)

这是我的测试代码

@Service
public class SomeService {

    private static final Logger logger = LoggerFactory.getLogger(SomeService.class);

    private final RequestContext requestContext; // @RequestScope + @Component Bean
    public SomeService(RequestContext requestContext) {
        this.requestContext = requestContext;
    }

    public void checkBean() {
        logger.info("Singleton Bean: {}, RequestScope Bean: {}", this, this.requestContext);
        String clientId = recommendContext.getClientId();
    }
}

下面的场景

  • 从控制器获取请求
  • SomeService由Controller注入
  • 每个请求都有自己的RequestContext Bean
  • 在控制器中,调用someService.checkBean()

我觉得奇怪的是

  • SomeService 是一个单例 bean
  • RequestContext 被声明为 final 变量,并且仅由构造函数发起
  • 但它似乎有效。

运行代码的结果如下所示

2021-06-14 09:56:26.010 INFO  23075 --- [nio-8888-exec-1] p.service.SomeService   : Singleton Bean: pkgs.service.SomeServiceImpl@3c65ee26, RequestScope Bean: pkgs.context.RequestContext@56867592
2021-06-14 09:56:30.933 INFO  23075 --- [nio-8888-exec-3] p.service.SomeService   : Singleton Bean: pkgs.service.SomeServiceImpl@3c65ee26, RequestScope Bean: pkgs.context.RequestContext@73ddb7a4
2021-06-14 09:56:31.687 INFO  23075 --- [nio-8888-exec-4] p.service.SomeService   : Singleton Bean: pkgs.service.SomeServiceImpl@3c65ee26, RequestScope Bean: pkgs.context.RequestContext@56b4f7c8
2021-06-14 09:56:32.352 INFO  23075 --- [nio-8888-exec-5] p.service.SomeService   : Singleton Bean: pkgs.service.SomeServiceImpl@3c65ee26, RequestScope Bean: pkgs.context.RequestContext@33469287

正如您所见,Service 是 Single 并且 RequestContext bean 对于每个请求都是唯一的。 我需要一些关于 spring 内部发生了什么的解释

谢谢

【问题讨论】:

    标签: spring-boot dependency-injection scope requestscope


    【解决方案1】:

    当 bean 是请求范围的时,Spring 会创建一个代理。每当调用此代理时,它都会委托给特定于当前请求的 bean 实例。

    在您的情况下,注入SomeService 并存储在requestContext final 变量中的RequestContext 实例是代理。如果您尝试在 Web 请求范围之外调用服务,则会失败,因为代理无法找到当前请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 2014-08-11
      • 1970-01-01
      • 2018-04-29
      相关资源
      最近更新 更多