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
SomeService
is injected by ControllerRequestContext
BeansomeService.checkBean()
The point I think strange is
SomeService
is a singleton beanRequestContext
is declared as a final
variable and only initiated by constructorThe 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 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.