Vaadin III: integración con Spring

Finalizo esta serie sobre Vaadin con esta tercera entrega cuyo título es Vaadin III: integración con Spring. En esta entrada, describiré la forma de integrar Spring con Vaadin aplicando el patrón MVP y, además, realizaré un ejemplo básico basado en los ejemplos descritos en la serie. Para aquel lector nuevo en la serie, en la primera entrada Vaadin I: introducción, realicé una breve descripción de Vaadin y un ejemplo básico tipo “Hola Mundo”; y, en la segunda entrada, Vaadin II: MVP con Guava, describo el patrón modelo vista presentador MVP utilizando el componente EventBus de la librería Guava para la gestión de eventos.

Definición del caso práctico

La aplicación ejemplo es prácticamente idéntica a los ejemplos de las entradas anteriores,la diferencia, la utilización del framework Spring. La funcionalidad que defino es muy sencilla ya que mi objetivo es la descripción de la integración y no realizar una aplicación compleja.

Visualmente, la aplicación es idéntica, pero en el objeto Label empleado para mostrar texto de salida, al arrancar la aplicación, se muestra un texto que se genera en un servicio Spring. La imagen de la aplicación es la siguiente:

VaadinIII_spring

VaadinIII_spring

Configuración de Spring en Vaadin

Para emplear Spring en la aplicación, es necesario definir en el fichero pom.xml del proyecto las dependencias de Spring. Las dependencias que utilizo son: spring-core, spring-beans, spring-context y spring-web; la versión de spring,  3.2.4.RELEASE . El contenido del pom es el siguiente:

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <version>${spring.version}</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>${spring.version}</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>${spring.version}</version>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-web</artifactId>
 <version>${spring.version}</version>
</dependency>

El contexto Spring se define en el fichero applicationContex.xml; en el cual, se define las referencias de los servicios de la aplicación. Los servicios se encuentran localizados en la carpeta es.directoandroid.service del proyecto. El contenido del fichero applicationContext.xml es el siguiente:

<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd">
 <context:component-scan base-package="es.directoandroid.service" />
</beans>

En el fichero de configuración  web.xml, se añade la referencia del contexto spring, y, se añade el Listener del cargador del contexto Spring. El snippet con el contenido a añadir es el siguiente:

... 
<context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param> 
...
<listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...

La funcionalidad que se añade en el servlet de la aplicación para la utilización de Spring es muy sencilla, simplemente, se referencia al contexto Spring y, además, definimos un método para obtener la referencia de los servicios definidos en la aplicación. Si se recuerda la entrada anterior, la idea es la misma que la utilizada para la obtención de la referencia al objeto EventBus. La funcionalidad que se añade al servlet MiVaadinServlet es la siguiente:

...
private ApplicationContext applicationContext;
…
@Override
public void init() throws ServletException {
 super.init();
 this.eventBus = new EventBus();
 this.applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); }
...
public Object getContextBean(final String name) {
 return applicationContext.getBean(name);
}
...

Se realiza la Definición del contexto Spring en el servlet de Vaadin porque no se pueden definir como componentes Spring los elementos que intervienen en el UI o CustomComponent de Vaadin para poder realizar la inyección de los elementos. Así, la única manera de realizar la integración de Spring en Vaadin es mediante el contexto de la aplicación Vaadin el cual contiene la referencia al contexto definido en el servlet. Para ello, he empleado un clase que encapsula el acceso al contexto de los servicios; esta clase, es la clase MiSpringInyector la cual define los métodos de los servicios existentes; en nuestro ejemplo, el método que carga el servicio es el siguiente:

public static Servicio servicio() {
 return (ServicioImpl) ((MiVaadinServlet) VaadinServlet.getCurrent()).getContextBean("servicio");
}

MVP (Modelo Vista Presentador) Y Spring

El modelo que he utilizado es una clase con los valores de entrada y de salida.

La vista es la misma que en la entrada anterior.

El presentador es el mismo que el caso anterior salvo que se utiliza la clase MiSpringInyector para cargar el servicio Spring definido como atributo de la clase presentadora. La carga del servicio se realiza en el método bind() de la siguiente forma:

...
private Servicio servicio;
...
bind(){
servicio = MiSpringInyector.servicio();
...
}
...

La clase de la aplicación VaadinIII, en su método init, realiza la creación del modelo, la vista y el presentador, así como, la creación del Layout y del bus para la gestión de eventos. El método init es el siguiente:

@Override
protected void init(VaadinRequest request) {
 final VerticalLayout content = new VerticalLayout();
 content.setMargin(true);
 setContent(content);
 EventBus bus = ((MiVaadinServlet) VaadinServlet.getCurrent()).getBus();
 EjemploModel model = new EjemploModel("Servicio Dummy", "Salida Spring:");
 EjemploVista vista = new EjemploVista();
 EjemploPresenter presenter = new EjemploPresenter(vista, model, bus);
 bus.register(presenter);
 content.addComponent(vista);
}

Conclusiones

El ejemplo descrito es muy sencillo y, simplemente, he querido reflejar la forma en la cual se integra Spring con Vaadin. La debilidad de Vaadin es que la integración con Spring es a través del contexto y no se puede aplicar la inyección de dependencias de los componentes Vaadin con los mecanismos que proporciona Spring.

Si se desea el código se puede acceder aquí.

4 pensamientos en “Vaadin III: integración con Spring

  1. rgaaray dice:

    Muy buen artículo… Una pregunta tienes un ejemplo de vaadin con spring security?

  2. Enhorabuena por el blog. Te invito a que visites el mío, donde tengo un par de post sobre Vaadin y Spring, usando 2 enfoques diferentes en cada uno:

    Aprendiendo Vaadin #6: Usando SpringVaadinIntegration con soporte de navegación

    Aprendiendo Vaadin #4: Agregando Spring

    Saludos!

Deja un comentario