views:

4396

answers:

3

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.

+2  A: 

I've found one way to do it:

WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
SpringifiedJobbie jobbie = (SpringifiedJobbie)context.getBean("springifiedJobbie");
Sophie Tatham
+5  A: 

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");
Jim Huang
Nice, thank you.
Sophie Tatham
What is the advantage to doing it this way and not using WebApplicationContextUtils? Either way it's tied to Spring.
Elliot
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.
Jim Huang
+5  A: 

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.

Oliver Gierke