#spring-boot #dependency-injection #scope #requestscope
Вопрос:
Он работает, насколько я проверил. Но я не понимаю, почему и как это работает.(Также я не уверен, что это безопасно использовать в производстве)
Вот мой тестовый код
@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
вводится контроллером- У каждого запроса есть свой собственный
RequestContext
компонент - В контроллере, позвоните
someService.checkBean()
Дело в том, что я считаю странным, что
SomeService
является одноэлементным бобом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
Как вы можете видеть, сервис единичен, а компонент RequestContext уникален для каждого запроса.
Мне нужно какое-то объяснение того, что происходит внутри spring
Спасибо
Ответ №1:
Когда компонент имеет область запроса, Spring создает прокси-сервер. Всякий раз, когда вызывается этот прокси-сервер, он делегирует экземпляр компонента, специфичного для текущего запроса.
В вашем случае RequestContext
экземпляр, который вводится в SomeService
переменную и хранится в requestContext
final
ней, является прокси-сервером. Если вы попытаетесь вызвать службу за пределами веб-запроса, это приведет к сбою, так как прокси-сервер не сможет найти текущий запрос.