Al igual que con Vaadin 6 hay que seguir una serie de pasos previos, pero son un poco diferentes gracias a la existencia de la clase UIProvider, así que comencemos con los pasos para conseguir esta integración:
- Creación del proyecto maven:
mvn archetype:generate \ -DarchetypeGroupId=com.vaadin \ -DarchetypeArtifactId=vaadin-archetype-application \ -DarchetypeVersion=7.0.5 \ -DgroupId=com.javiserrano \ -DartifactId=vaadin7.spring \ -Dversion=1.0-SNAPSHOT \ -Dpackaging=war - Adición de las dependencias de spring al archivo pom generado en la ejecución del punto anterior:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.2.2.RELEASE</version> </dependency>
- Modificación del archivo web.xml generado por el arquetipo sustituyéndolo por el siguiente, o bien añadiendo desde la linea 9 a la 18 ambas incluidas y desde la 32 a la 36 ambas incluidas, quedando de la siguiente manera:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Vaadin Web Application</display-name> <context-param> <description>Vaadin production mode</description> <param-name>productionMode</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <servlet> <servlet-name>Vaadin Application Servlet</servlet-name> <servlet-class>com.vaadin.server.VaadinServlet</servlet-class> <init-param> <description>Vaadin UI to display</description> <param-name>UI</param-name> <param-value>com.javiserrano.MyVaadinUI</param-value> </init-param> <init-param> <description>Application widgetset</description> <param-name>widgetset</param-name> <param-value>com.javiserrano.AppWidgetSet</param-value> </init-param> <init-param> <description>Vaadin UI Provider</description> <param-name>UIProvider</param-name> <param-value>com.javiserrano.MyUIProvider</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Vaadin Application Servlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> - Debemos crear el archivo context.xml en la carpeta src/main/webapp/WEB-INF/spring con el siguiente contenido:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:annotation-config /> <context:component-scan base-package="com.javiserrano" /> </beans> - Ahora toca la creación de la clase "Inyectora", que quedará así:
package com.javiserrano; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.support.WebApplicationContextUtils; public class Inject { public static void inject( Object component ) { ApplicationContext context = getApplicationContext(); AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory(); beanFactory.autowireBeanProperties( component, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false ); } private static ApplicationContext getApplicationContext() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = attributes.getRequest(); HttpSession session = request.getSession( false ); ServletContext servletContext = session.getServletContext(); WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext( servletContext ); return context; } } - Ahora vamos a crear el UIProvider con el siguiente contenido:
package com.javiserrano; import com.vaadin.server.UIClassSelectionEvent; import com.vaadin.server.UICreateEvent; import com.vaadin.server.UIProvider; import com.vaadin.ui.UI; @SuppressWarnings("serial") public class MyUIProvider extends UIProvider { @Override public Class getUIClass(UIClassSelectionEvent event) { return MyVaadinUI.class; } @Override public UI createInstance(UICreateEvent event) { UI instance = super.createInstance(event); Inject.inject(instance); return instance; } } - Ahora vamos a crear el servicio HelloService con el siguiente contenido:
package com.javiserrano; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service @Scope("prototype") public class HelloService { public String sayHello() { return "Hello Vaadiners from a Spring Service!!!"; } }NOTA: Es importante que todo aquello que queramos inyectar vía Spring tenga las anotaciones @Service o @Component para que Spring sea capaz de detectarlas e inyectarlas automáticamente. - Ahora toca modificar la clase principal, MyVaadinUI, creada automáticamente por el arquetipo para que quede de la siguiente forma:
package com.javiserrano; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; /** * The Application's "main" class */ @SuppressWarnings("serial") public class MyVaadinUI extends UI implements ClickListener{ @Autowired HelloService helloService; @Override protected void init(VaadinRequest request) { final VerticalLayout layout = new VerticalLayout(); layout.setMargin(true); setContent(layout); Button button = new Button("Click Me"); button.addClickListener((Button.ClickListener) this); layout.addComponent(button); } public void buttonClick(ClickEvent event){ if (helloService != null){ Notification.show("The injected service says", helloService.sayHello(), Type.HUMANIZED_MESSAGE); } } } - Por último, probamos la aplicación ejecutando en un terminal:
mvn package jetty:run
Abrimos un navegador web y navegamos a http://localhost:8080/vaadin7.spring
Los fuentes los podéis descargar haciendo click en ... vaadin7.spring.zip
Como siempre, un saludo y a disfrutar!
Como siempre, un saludo y a disfrutar!
Hola Javi, gracias por tu post. Hago referencia a él en la última entrada de mi blog: http://dherrerabits.wordpress.com/2013/07/13/aprendiendo-vaadin-4-agregando-spring/
ResponderEliminarMe ha resultado muy útil. Gracias y saludos!