Используйте ThreadLocal для передачи данных области запроса

Я создал API для отдыха Java 8, используя Spring Boot 2. Конечные точки контроллера можно аннотировать пользовательской аннотацией @DataAware. Активен HandlerInterceptor, который проверяет, сопоставлен ли текущий запрос методу с этой аннотацией. Если это так, я хочу, чтобы перехватчик проанализировал определенный заголовок запроса и сделал результирующий объект доступным для всего потока, обрабатывающего этот запрос.

Например:

  1. Запрос содержит заголовок "specialData a:b:c"
  2. Конечная точка помечена @DataAware
  3. DataInterceptor проанализирует заголовок и создаст объект List parsedData = "a", "b" и "c".
  4. DataInterceptor сделает что-то вроде ThreadForThisRequest.addProperty("data",myParsedData);
  5. В разных местах моего приложения классы и объекты должны иметь возможность ссылаться на parsedData, и следует использовать значение, активное в данный момент в этом потоке.
  6. Когда в систему поступает другой запрос (возможно, одновременно), оба потока не должны видеть разобранные данные друг друга. ЕСЛИ один и тот же поток используется повторно, предыдущие сохраненные данные должны быть удалены или переопределены.

Я хотел использовать MDC (сопоставленный диагностический контекст) для этой цели, но это похоже на антипаттерн для хранения данных в относительно скрытой «глобальной» контекстной карте.

Мне не нравятся свойства запроса, потому что тогда мне пришлось бы передавать объект запроса везде в моем приложении. Гораздо проще запрограммировать что-то, что выглядит как «публичный статический окончательный XXX», но на самом деле ограничено только этим запросом (потоком).

Я наткнулся на ThreadLocal и хотел убедиться, что он делает то, что я думаю. Если я введу следующее поле:

public static ThreadLocal<List<String>> requestSpecificData

Тогда каждый раз, когда мое приложение использует этот объект, будут предоставлены только данные ЭТОГО запроса, потому что каждый запрос обрабатывается своим собственным потоком? Делает ли встроенный Tomcat Spring Web или Spring Boot какие-то другие причудливые вещи с потоками или пересылкой запросов (в другие потоки?), Так что в моей конечной точке контроллера могут отсутствовать данные или видеть данные предыдущих запросов вместо своих собственных?


person user1884155    schedule 19.05.2019    source источник
comment
Просто используйте bean-компонент с областью запроса. Вставьте его в свой перехватчик. Заполните его в методе перехвата. Введите его в каждый компонент, где вам нужна информация. docs.spring. io/spring/docs/current/spring-framework-reference/   -  person JB Nizet    schedule 19.05.2019
comment
@JBNizet Спасибо за эту ссылку. Нужно ли мне беспокоиться о внедрении bean-компонента с областью запроса в bean-компонент с областью singleton, как упоминается в этой ссылке, или аннотации @Component@RequestScoped в моем классе bean-компонента автоматически обрабатывают проксирование? См. этот вопрос: stackoverflow.com/questions/56217321/   -  person user1884155    schedule 20.05.2019
comment
Да, он обрабатывает прокси автоматически.   -  person JB Nizet    schedule 20.05.2019