0

I made a Java 8 rest API using Spring Boot 2. The controller endpoints can be annotated with a custom annotation @DataAware. There is an HandlerInterceptor active which checks if the current request is mapped to a method with this annotation. If it is, I want the interceptor to parse a certain header of the request and make the resulting object available throughout the entire thread that handles that request.

For example:

  1. A request contains header "specialData a:b:c"
  2. The endpoint is annotated with @DataAware
  3. The DataInterceptor will parse the header and create an object List parsedData = "a", "b" and "c".
  4. The DataInterceptor will do something like ThreadForThisRequest.addProperty("data",myParsedData);
  5. At various places in my application, classes and objects need to be able to refer to the parsedData, and the value that is currently active on that thread should be used.
  6. When another request enters the system (possibly at the same time), both threads should not be able to see each other's parsed data. IF the same thread is reused, the previous stored data should be removed or overridden

I wanted to use MDC (Mapped Diagnostic Context) for this purpose, but it seems like an antipattern to store data in a relatively hidden "global" context map.

I don't like request properties because then I would have to pass the request object everywhere in my application. It's much easier to program something that looks like a "public static final XXX", but is actually scoped to that request (thread) only.

I stumbled upon ThreadLocal and wanted to be sure it does what I think it does. If I introduce the following field:

public static ThreadLocal<List<String>> requestSpecificData

Then every time my application uses this object, only the data of THAT request will be given because every request is handled by its own thread? Does Spring Web or Spring Boot's embedded Tomcat do some other quirky stuff with threads or forwarding of requests (to other threads?) so that my controller endpoint could be missing data or see a previous requests data instead of its own?

user1884155
  • 3,616
  • 4
  • 55
  • 108
  • 1
    Just use a request-scoped bean. Inject it in your interceptor bean. Populate it in its intercept method. Inject it in every bean where you need the information. https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-request – JB Nizet May 19 '19 at 17:13
  • @JBNizet Thanks for that reference. Do I need to worry about injecting a request-scoped bean into a singleton-scoped bean like that link mentions, or does the @Component@RequestScoped annotations on my bean class handle the proxying automatically? Please see this question: https://stackoverflow.com/questions/56217321/does-springs-requestscope-automatically-handle-proxying-when-injected-in-singl – user1884155 May 20 '19 at 08:50
  • Yes, it handles the proxy automatically. – JB Nizet May 20 '19 at 09:27

0 Answers0