как реализовать весной общую, не строго похожую на http "RequestScope" область видимости?
Мне нужно реализовать обобщенный RequestScope, который будет работать не только для HTTP-запросов, но и для HTTP-запросов. Думайте об этом как об обобщенном RequestScope для произвольной точки входа в приложение. Веб-сервис, кафка, отдых, JMS, что угодно. Tbh Я действительно удивлен, что это не существует в легкодоступном виде. К сожалению, даже после долгого чтения я не получаю ответов ниоткуда, мне, вероятно, не хватает некоторых фундаментальных знаний о Spring.
Эта задача в принципе тривиальна. Поскольку обработка запроса (в рассматриваемом случае) связана с одним потоком, все, что нам нужно сделать, это использовать ThreadLocal и иметь место, где разместить логику инициализации и уничтожения. Но я изо всех сил пытаюсь найти какой-либо не очень упрощенный пример / документацию, как это сделать весной. Может ли кто-нибудь сослаться на любой источник или привести пример?
Но чтобы начать какое-то решение . Я хотел бы сказать, что область видимости называется «поток», и иметь возможность внедрять сервис, используя эту область. По сути, я просто хочу вызвать метод этой службы, чтобы получить информацию о «записи», и это должно остаться таким же для той же «записи». Хорошо, давайте создадим и зарегистрируем настраиваемую область с именем thread:
@Bean
public CustomScopeConfigurer customScope () {
CustomScopeConfigurer configurer = new CustomScopeConfigurer ();
configurer.addScope("thread", new SimpleThreadScope());
return configurer;
}
чтобы не использовать его для наших услуг:
@Slf4j
@Service
@Scope(scopeName = "thread", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ThreadScopedSomething {
//....
SimpleThreadScope
не поддерживает уничтожение bean-компонентов, поэтому мы можем использовать [1] или [2], которые по какой-то причине не были включены в spring (недокументировано в тикете, они просто ссылаются на javadoc). Но наш вариант использования не нуждается в какой-либо логике уничтожения, поэтому мы могли бы справиться с этим, поскольку минимальное состояние, содержащееся в ThreadScopedSomething, будет просто перезаписано. Итак, это создает bean-компонент для каждого потока, обычно в threadpool, поэтому через некоторое время у нас будет bean-компонент для каждого потока, и он остановится на этом. Поэтому нам нужно ввести некоторую логику для выполнения логики инициализации / уничтожения для каждой точки входа. Для отдыха, все сообщения и т. Д. Давайте обсудим отдых, скажем, кафка, кажется, легче сделать. Я упоминал, что это легко сделать с
@ControllerAdvice
, но без какого-либо упоминания о том, как, и вся документация / образцы вращаются вокруг ведения журнала без каких-либо предложений, как применить его в более общем сценарии использования. Так что я могу только придумать
WebMvcConfigurer
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HandlerInterceptor() {
и переопределить
preHandle
а также
afterCompletion
который позвонит
init
а также
reset
на автосоединении с резьбой
ThreadScopedSomething
пример. То же самое нужно сделать для каждой точки входа.
Кажется, работает. Кажется уродливым и хакерским подходом, черт возьми. Может ли кто-нибудь раскритиковать и предложить лучшее решение / подход? Как это сделать правильно?
[1] https://github.com/jyore/spring-scopes[2] https://github.com/devbury/spring-boot-starter-threadscope