Integrar Spring en nuestro proyecto JSF/PrimeFaces

Hola Gente,

avancemos un poco más en nuestro proyecto.

En esta ocasión, la idea es incorporar Spring al proyecto JSF/PrimeFaces que venimos desarrollando.

Introducción:
Antes de comenzar diré un par de palabras sobre Spring, comencemos por decir que es uno de los frameworks más extendidos para desarrollo de aplicaciones Java que requieran escalar, fácil mantenimiento y testing entre otras cosas. En este tutorial no me extenderé en teoría acerca de Spring, para ello existen muchos y muy buenos tutoriales y documentos, por ejemplo este.

Objetivo:
Configurar Spring y hacer que maneje nuestros beans, beans que hasta ahora manejaba JSF.

Descargando Spring:
Lo primero que debemos hacer es descargar Spring, se puede descargar de este sitio. Yo he utilizado particularmente la versión 3.2.1 que he descargado desde aquí, aunque en el momento de escribir este tutorial ya se encuentra disponible la versión 3.2.2.

Configurando las librerías en el proyecto:
Una vez que descargamos Spring, debemos descomprimir el archivo y copiar (o linkear) a nuestro proyecto (carpetaWEB-INF/lib) los siguientes archivos:

spring-beans-3.2.1.RELEASE.jar
spring-context-3.2.1.RELEASE.jar
spring-context-support-3.2.1.RELEASE.jar
spring-core-3.2.1.RELEASE.jar
spring-expression-3.2.1.RELEASE.jar
spring-instrument-3.2.1.RELEASE.jar
spring-instrument-tomcat-3.2.1.RELEASE.jar
spring-instrument-tomcat-3.2.1.RELEASE.jar
spring-jdbc-3.2.1.RELEASE.jar
spring-tx-3.2.1.RELEASE.jar
spring-web-3.2.1.RELEASE.jar
spring-webmvc-3.2.1.RELEASE.jar

También debemos copiar la implementación de JSF que hasta ahora la utilizábamos mediante una referencia de librería de usuario:

javax.faces-2.1.17.jar

También necesitamos:

commons-logging-1.1.1.jar

Antes teníamos:

mysql-connector-java-5.1.17.jar
primefaces-3.5.jar

Nos debería quedar algo así:

Archivo de configuración de Spring:Spring no es la excepción, basa su funcionamiento en archivos de configuración, el más importante es el que crearemos a continuación. En la carpeta WEB-INF debemos crear un archivo llamado applicationContext.xml, y el contenido será:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="https://www.springframework.org/schema/context"
  xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd">

</beans>

Configuración de web.xml
Ahora debemos decirle a nuestra aplicación web cual es el componente de Spring que procesará el inicio de Spring, entre otras cosas leer el archivo (applicationContext.xml) y crear el contexto y cual procesará los requerimientos http, para ello editamos el archivo WEB-INF/web.xml y agregamos los siguientes listeners:

  ...
  ...
  <display-name>pf</display-name>
  <listener>
     <listener-class>
       org.springframework.web.context.ContextLoaderListener
     </listener-class>
  </listener>
  <listener>
     <listener-class>
       org.springframework.web.context.request.RequestContextListener
     </listener-class>
  </listener>
  <welcome-file-list>
    <welcome-file>login.xhtml</welcome-file>
  </welcome-file-list>

  ...
  ...
 
Derivación del manejo de beans:
A esta altura ya tenemos funcionando Spring, solo restan dos tareas:
 
1)  "Decirle" a JSF que Spring manejará los beans. Siempre es una clase la encargada de procesar y resolver las expresiones utilizadas mediante lenguaje de expresiones (EL), JSF tiene una clase asignada por defecto, lo que haremos es cambiar esa clase, para ello editamos el archivo de configuración de JSF WEB-INF/faces-config.xml y  agregamos al inicio:
 

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config xmlns="https://java.sun.com/xml/ns/javaee"
  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://java.sun.com/xml/ns/javaee 
  https://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1"> 
  <application> 
   <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
  </application>
...
...

2) "Mudar"la configuración del manejo de beans desde JSF a Spring, para los cual:
2.a) Editamos el archivo de configuración de JSF (el del punto anterior) WEB-INF/faces-config.xml y comentamos (<!-- -->) las definiciones de beans que teníamos, el archivo quedará así:
 

<?xml version="1.0" encoding="UTF-8"?> 
<faces-config xmlns="https://java.sun.com/xml/ns/javaee"
  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://java.sun.com/xml/ns/javaee 
  https://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd" version="2.1"> 
  <application> 
   <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
  </application>

  <!--  
    <managed-bean>
      <managed-bean-name>gaugeBean</managed-bean-name>
      <managed-bean-class>ar.com.magm.web.primefaces.GaugeBean</managed-bean-class>
      <managed-bean-scope>application</managed-bean-scope>
    </managed-bean>
    <managed-bean>
      <managed-bean-name>ventasBean</managed-bean-name>
      <managed-bean-class>ar.com.magm.web.primefaces.VentasBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
    <managed-bean>
      <managed-bean-name>loginBean</managed-bean-name>
      <managed-bean-class>ar.com.magm.web.primefaces.LoginBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>
  -->
</faces-config>

 
2.b) Editamos el archivo de configuración de Spring WEB-INF/applicationContext.xml y agregamos la configuración necesaria, el archivo quedará así:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="https://www.springframework.org/schema/context"
  xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd">

  <bean id="gaugeBean" class="ar.com.magm.web.primefaces.GaugeBean" scope="singleton"/>
  <bean id="ventasBean" class="ar.com.magm.web.primefaces.VentasBean" scope="session"/>
  <bean id="loginBean" class="ar.com.magm.web.primefaces.LoginBean" scope="session"/>

</beans>

Notemos que para definir cada bean, es necesario solo un elemento XML si usamos Spring. Lo que en JSF definía el nombre o id del bean (<managed-bean-scope>) era un elemento, en el caso de Spring se trata del atributo id, al igual que la clase que implementa el bean que en Spring también es un atributo. En Spring definimos el alcance y ciclo de vida de los beans con el atributo scope, en el caso de session, es igual que lo hacíamos con JSF, en el caso que necesitemos que un bean sea único para toda la aplicación  nuestro scope será ahora singleton.
 
Bien, eso es todo, si probamos la aplicación, esta seguirá comportándose como antes. En la interface gráfica no hay diferencias.
 
En breve continuaremos agregando características muy interesantes a nuestro proyecto.
 
Recuerden que pueden descargarse el war con el proyecto funcionando desde aquí, también pueden sacar del war las librerías (.jar). El proyecto completo sigue estando aquí.
 
Espero les sea de utilidad.
 
Tutorial anterior: https://jmagm.blogspot.com/2013/02/control-de-acceso-datos-automatizado.html
Próximo tutorial:
 
Saludos