spring-bootdependency-injectionscoperequestscope

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

The point I think strange is

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. I need some explanation of what is going on inside spring

Thanks


Solution

  • When a bean is request-scoped, Spring creates a proxy. Whenever this proxy is called, it delegates to an instance of the bean that is specific to the current request.

    In your case, the RequestContext instance that is injected into SomeService and stored in the requestContext final variable is the proxy. 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.