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
SomeServiceis injected by Controller- Every request has its own
RequestContextBean - In Controller, call
someService.checkBean()
The point I think strange is
SomeServiceis a singleton beanRequestContextis declared as afinalvariable and only initiated by constructor- 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. I need some explanation of what is going on inside spring
Thanks
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
RequestContextinstance that is injected intoSomeServiceand stored in therequestContextfinalvariable 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.