javaspringspring-bootautowiredpostconstruct

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

  • Please be aware of the best practice for accessing the ServletContext: You shouldn't do it in your main application class, but e. g. a controller.

    Otherwise try the following:

    Implement the ServletContextAware interface and Spring will inject it for you.

    Remove @Autowired for the variable.

    Add setServletContext method.

    @SpringBootApplication
    public class MyApp implements ServletContextAware {
    
        private BeanThing beanThing = null;
    
        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
        }
    
        public void setServletContext(ServletContext servletContext) {
            this.context = servletContext;
        }
    
    
    }