Issue
I'm very new to Spring and web development in general, so please bear with me if the question seems confused or incomplete...
I'm currently working on a Spring project in which there is a bean I'll call 'requestContext' which holds some commonly used data. This bean is request-scoped, and it appears to get populated by a servelet filter (a child of GenericFilterBean).
I'm trying to access the info held by this bean from another bean (i'll call UserBean) in the preHandle method of a HandlerInterceptor. In UserBean I use @AutoWired to access the bean as below:
@Autowired
private RequestContext requestContext;
Then in one of UserBeans methods I try to access the necessary data. The problem is that the request context contains all null values. I thought there might be some lifecycle issue, being unfamiliar with filters, but using some breakpoints I can see that the filter is executed before the handlerInterceptor, and I can see the request context data being set. That being the case I would expect to at least be able to access it in the preHandle method of the interceptor if not the others.
The rest of the application (including filter, handler interceptor) is all existing/known working code, so I don't think I have any setup issues up to the point where I'm trying to use that bean. There's just some problem with either my expectations, or with how I'm trying to access it.
UPDATE: I found one example of a class that actually consumes the requestContext. It's another filter (but implements Filter directly vs extending GenericFilterBean). This filter calls
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this)
in its init() method. I noticed that if I make this call just before trying to access requestContext, then it is instantiated with the values I expect (also notice that if I do it in a default constructor it does not work). Something tells me this is not the rights solution in my case, but hopefully this sheds some light on the issue.
Trying to read up on SpringBeanAutowiringSupport to understand better. I think if I'm understanding it correctly, this indicates my bean does not currently have access to the WebApplicationContext, so the Autowiring is not working by default until this call is made (once the call is made, subsequent requests don't seem to require it). Does this indicate some issue with the way I've configured the bean (it's not registered with IoC correctly?) Aagain, please forgive my lack of knowledge on spring, I still don't know that much about this stuff like IoC...
Solution
Well, it looks like ElderMael was onto something, and my question ends up being answered by this question: How are Spring HandlerInterceptors instantiated?
In absence of defining a scope for the interceptor, and beans it uses, they are singletons, and they are created with one instance of the requestContext. When subsequent instances are created for each request, I still have my old original instance. Adding the processInjectionBasedOnCurrentContext method I believe is just processing the autowiring again, and finding the newly created instance. I'll have to think about the ideal way to solve that, but I think because the HandlerInterceptor has no need to retain state, I could probably make that and the related beans request-scoped as well.
Answered By - ryoaska
Answer Checked By - Clifford M. (JavaFixing Volunteer)