简体   繁体   English

是否能够使用 Spring 中的构造函数注入将 RequestScope bean 注入 Singleton bean?

[英]Is it able to inject RequestScope bean into Singleton bean using Constructor Injection in Spring?

It is working as far as I tested.据我测试,它正在工作。 But I do not get it why and how it works.(Also I am not sure it is safe to use in production)但我不明白它为什么以及如何工作。(我也不确定在生产中使用它是否安全)

Here is my testCode这是我的测试代码

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

The Scenario like below像下面这样的场景

  • Get a Request from Controller从 Controller 获取请求
  • SomeService is injected by Controller SomeService由 Controller 注入
  • Every request has its own RequestContext Bean每个请求都有自己的RequestContext Bean
  • In Controller, call someService.checkBean()在 Controller 中,调用someService.checkBean()

The point I think strange is我认为奇怪的一点是

  • SomeService is a singleton bean SomeService是一个 singleton bean
  • RequestContext is declared as a final variable and only initiated by constructor RequestContext被声明为final变量,仅由构造函数发起
  • However it seems works.但是,它似乎有效。

The result of running code looks like below运行代码的结果如下所示

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

As you can see Service is Single and RequestContext bean is unique for every request.如您所见,Service 是 Single 并且 RequestContext bean 对于每个请求都是唯一的。 I need some explanation of what is going on inside spring我需要一些关于 spring 内部发生的事情的解释

Thanks谢谢

When a bean is request-scoped, Spring creates a proxy.当 bean 是请求范围的时,Spring 创建一个代理。 Whenever this proxy is called, it delegates to an instance of the bean that is specific to the current request.每当调用此代理时,它都会委托给特定于当前请求的 bean 实例。

In your case, the RequestContext instance that is injected into SomeService and stored in the requestContext final variable is the proxy.在您的情况下,注入SomeService并存储在requestContext final变量中的RequestContext实例是代理。 If you tried to call the service outside the scope of a web request it would fail as the proxy would not be able to find the current request.如果您尝试在 web 请求的 scope 之外调用服务,它将失败,因为代理无法找到当前请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM