'How to get access to ServletContext inside of an @Configuration or @SpringBootApplication class
I'm attempting to update an old Spring application. Specifically, I'm trying to pull all of the beans out of the old xml-defined form and pull them into a @SpringBootApplication format (while dramatically cutting down on the overall number of beans defined, because many of them did not need to be beans). My current issue is that I can't figure out how to make the ServletContext available to the beans that need it.
My current code looks something like this:
package thing;
import stuff
@SpringBootApplication
public class MyApp {
private BeanThing beanThing = null;
@Autowired
private ServletContext servletContext;
public MyApp() {
// Lots of stuff goes here.
// no reference to servletContext, though
// beanThing gets initialized, and mostly populated.
}
@Bean public BeanThing getBeanThing() { return beanThing; }
@PostConstruct
public void populateContext() {
// all references to servletContext go here, including the
// bit where we call the appropriate setters in beanThing
}
}
The error I get back: Field servletContext in thing.MyApp required a bean of type 'javax.servlet.ServletContext' that could not be found.
So... what am I missing? Is there something I'm supposed to be adding to the path? Is there some interface I need to implement? I can't provide the bean myself because the whole point is that I'm trying to access servlet context info (getContextPath() and getRealPath() strings) that I don't myself have.
Solution 1:[1]
Make the bean lazy and use a parameter:
@Lazy
@Bean
public BeanThing getBeanThing(ServletContext servletContext) {
return new BeanThing(servletContext);
}
It needs to be lazy because the ServletContext won't exist when the instance of the MyApp is created. When the ServletContext becomes available, Spring will remember it somewhere and it will be able to fill in the parameter.
To make this work, you just have to make sure the bean isn't requested before that.
Now you might have to create beans which need BeanThing earlier than that. The solution then is to inject a Provider<BeanThing> and make sure the provider is only used after the ServletContext exists (i.e. not in @PostConstruct or similar).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Aaron Digulla |
