Thursday, March 24, 2011

Access Spring beans from a servlet in JBoss

I want to write a simple servlet in JBoss which will call a method on a Spring bean. The purpose is to allow a user to kick off an internal job by hitting a URL.

What is the easiest way to get hold of a reference to my Spring bean in the servlet?

JBoss web services allow you to inject a WebServiceContext into your service class using an @Resource annotation. Is there anything comparable that works in plain servlets? A web service to solve this particular problem would be using a sledgehammer to crush a nut.

From stackoverflow
  • I've found one way to do it:

    WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    SpringifiedJobbie jobbie = (SpringifiedJobbie)context.getBean("springifiedJobbie");
    
  • Your servlet can use WebApplicationContextUtils to get the application context, but then your servlet code will have a direct dependency on the Spring Framework.

    Another solution is configure the application context to export the Spring bean to the servlet context as an attribute:

    <bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
      <property name="attributes">
        <map>
          <entry key="jobbie" value-ref="springifiedJobbie"/>
        </map>
      </property>
    </bean>
    

    Your servlet can retrieve the bean from the servlet context using

    SpringifiedJobbie jobbie = (SpringifiedJobbie) getServletContext().getAttribute("jobbie");
    
    Sophie Tatham : Nice, thank you.
    Elliot : What is the advantage to doing it this way and not using WebApplicationContextUtils? Either way it's tied to Spring.
    Jim Huang : The mechanism to populate the servlet context attribute does not have to be implemented using Spring. A filter or another servlet that runs at startup can populate the servlet context attribute.
  • There is a much more sophisticated way to do that. There is SpringBeanAutowiringSupportinside org.springframework.web.context.support that allows you building something like this:

    public class MyServlet extends HttpServlet {
    
      @Autowired
      private MyService myService;
    
      public void init(ServletConfig config) {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,
          config.getServletContext());
      }
    }
    

    This will cause Spring to lookup the ApplicationContext tied to that ServletContext (e.g. created via ContextLoaderListener) and inject the Spring beans available in that ApplicationContext.

0 comments:

Post a Comment