Oliver Drotbohm Archive About Tags

Neglected classes in Spring - Part III

April 7th, 2010

Java web application developers often face the need to inject a regular Spring bean into a non-Spring-managed artifact like a Servlet or a JSP tag.. If you browse the web for you find various quite outdated solutions to it. No offense, by the time being these were quite appropriate solutions. One of them you’ll probably will find is the following:

public class MyServlet extends HttpServlet {

  private MyService service;

  @Override
  public void init(ServletConfig config) {

    ServletContext context =
      config.getServletContext();

    ApplicationContext ctx =
      WebApplicationContextUtils.
        getRequiredWebApplicationContext(context);

    service = ctx.getBean(MyService.class);
  }
}

Let’s recap what we just have done. First we need to get access to the ServletContext of the web application. A Spring WebApplicationContext that was registered by a ContextLoaderListener will be registered in the ServletContext under a special name the framework knows, so that WebApplicationContextUtils can then look it up and hand it out to you to manually retrieve Spring beans from it.

Okay, that get’s the job done. But we can reduce the effort and go a much nicer way, that reduces the amount of boilerplate even more. Spring 2.5.1 introduced a tiny helperclass SpringBeanAutowiringSupport which is residing in org.springframework.web.context.support spending a rather unregarded life. It offers a method processInjectionBasedOnCurrentContext(Object target) that automatically injects Spring beans to properties of the given target using the usual annotation driven suspects (@Autowired, @Resource, @Inject). So our sample code turns into something like this:

public class MyServlet extends HttpServlet {

  @Inject
  private MyService service;

  @Override
  public void init() {
    SpringBeanAutowiringSupport.
      processInjectionBasedOnCurrentContext(this);
  }
}

Done. Note, that we override the init method without the ServletConfig parameter as the called method looks up the actual ApplicationContext from a static map held in ContextLoader which inherits from. If you need to lookup beans from an ApplicationContext tied to a particular ServletContext you can use processInjectionBasedOnServletContext(Object target, ServletContext servletContext) and hand it the appropriate instances.

P.S.: Thanks to Eberhard Wolff for pointing me at this.

blog comments powered by Disqus