I wanted to leverage on the solution provided by Sotirios Delimanolis but adding transparent autowiring to the mix.
The idea is to turn plain servlets into autowire-aware objects.
So I created a parent abstract servlet class that retrieves the Spring context, gets and autowiring-capable factory and uses that factory to autowire the servlet instances (the subclasess, actually). I also store the factory as an instance variable in case the subclasses need it.
So the parent abstract servlet looks like this:
public abstract class AbstractServlet extends HttpServlet {
protected AutowireCapableBeanFactory ctx;
@Override
public void init() throws ServletException {
super.init();
ctx = ((ApplicationContext) getServletContext().getAttribute(
"applicationContext")).getAutowireCapableBeanFactory();
//The following line does the magic
ctx.autowireBean(this);
}
}
And a sevlet subclass looks like this:
public class EchoServlet extends AbstractServlet {
@Autowired
private MyService service;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.getWriter().println("Hello! "+ service.getMyParam());
}
}
Notice the only thing EchoServlet needs to do is to declare a bean just in common Spring practice. The magic is done in the init() method of the superclass.
I haven't tested it thoroughly. But it worked with a simple bean MyService that also gets a property autowired from a Spring-managed properties file.
Enjoy!
Note:
It's best to load the application context with Spring's own context listener like this:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Then retrieve it like this:
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
ctx = context.getAutowireCapableBeanFactory();
ctx.autowireBean(this);
Only spring-web library needs to be imported, not spring-mvc.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…