I lately became interested in Vaadin, another web framework but where everything is done on the server side: no need for developers to learn HTML, CSS nor JavaScript. Since Vaadin adress my remarks about web applications being to expensive because of a constant need of well-rounded developers, I dug a little deeper: it will probably be the subject of another post.
Anyway, i became a little disappointed when I wanted to use my favourite Dependency Injection framework, namely Spring, in Vaadin. After a little Google research, I found the Vaadin Wiki and more precisely the page talking about Vaadin Spring Integration. It exposes two ways to integrate Spring in Vaadin.
The first one uses the Helper "pattern", a class with static method that has access to the Spring application context. IMHO, those Helper classes should be forgotten now we have DI since they completely defeat its purpose. If you need to explicitly call the Helper static method in order to get the bean, where’s the Inversion of Control?
The second solution uses Spring proprietary annotation @Autowired
in order to use DI.
Since IoC is all about decoupling, I’m vehemently opposed to coupling my code to the Spring framework.
Since neither option seemed viable to me, let me present you the one I imagined:
it is very simple and consists of subclassing the Vaadin’s AbstractApplicationServlet
and using it instead of the classical ApplicationServlet
.
public class SpringVaadinServlet extends AbstractApplicationServlet {
/** Class serial version unique identifier. */
private static final long serialVersionUID = 1L;
private Class clazz;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
config.getServletContext());
Application application = (Application) wac.getBean("application", Application.class);
clazz = application.getClass();
}
/**
* Gets the application from the Spring context.
*
* @return The Spring bean named 'application'
*/
@Override
protected Application getNewApplication(HttpServletRequest request)
throws ServletException {
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(
request.getSession().getServletContext());
return (Application) wac.getBean("application", Application.class);
}
/**
* @see com.vaadin.terminal.gwt.server.AbstractApplicationServlet#getApplicationClass()
*/
@Override
protected Class getApplicationClass()
throws ClassNotFoundException {
return clazz;
}
}
This solution is concise and elegant (according to me). Its only drawback is that it couples the servlet to Spring. But a class-localized coupling is of no consequesence and perfectly acceptable. Morevoer, this lets you use Spring autowiring mechanism, JSR 250 autowiring or plain old XML explicit wiring.