Cómo trabajar con JSF2 y el soporte de inyección de dependencias de Spring
0. Índice de contenidos.
- 1. Introducción.
- 2. Entorno
- 3. Configuración
- 4. A nivel de controlador
- 5. A nivel de interfaz JSF
- 6. Conclusiones
1. Introducción
En este tutorial explicaré brevemente como trabajar con JSF2 y el soporte de inyección de dependencias de Spring. El objetivo no es profundizar en el tema sino
fijar la atención en algunos puntos de interes para entender mejor el entorno en el que trabajamos. De esta manera aprovecharemos al máximo las posibildades que nos ofrecen los frameworks en los que nos apoyamos a la hora de construir nuestras aplicaciones.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware : Portátil Mac Book Pro 15″ (2,6 Ghz Intel Core i7, 4 GB DDR3).
- Sistema Operativo:Mac OS X Snow Leopard 10.6.7
- JSF 2 – Mojarra-2.0.3
- Spring – 3.1.0.M1
3. Configuración
En fichero de configuración de JSF faces-config.xml incluimos:
1 2 3 4 5 |
... <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> .... |
De esta menera estamos activando el soporte de Spring para la inyección de dependencias de tal forma que JSF sabrá que si no encuentra un bean
bajo su contexto debe ir a buscarlo al contexto de Spring. Esto supone una gran ventaja en determinadas situaciones como veremos a continuación.
4. A nivel de controlador
Una situación muy habitual que nos encontraremos a la hora de trabajar con JSF2 es la necesidad de realizar inyección de dependecias a nivel de controlador,
es decir, desde clases anotadas con @ManagedBean y publicadas en el contexto de JSF. Para ello JSF2 nos proporciona la anotación @ManagedProperty aunque como nos comentaba nuestro compañero Alex en el tutorial
JSF 2 ya está aquí !!!
The JSF Return, ahora más sencillo que nunca !!! JSF2 tiene una limitación al respecto ya que solo busca los bean
publicados en el directorio clases del proyecto web. Esta limitación nos impediria realizar la inyección de un bean que se encuentre empaquetado en un jar por lo que
no podríamos inyectar por ejemplo un bean de negocio.
Otra cosa importante respecto a relizar la inyección con esta anotación es que será necesario incluir el
método set del objeto en cuestión que se quiere inyectar.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@ManagedBean @ViewScoped public class TutorialsView implements Serializable { ... @ManagedProperty("#{tutorialNotification}") private TutorialNotification tutorialNotification; ... public void setTutorialNotification(TutorialNotification tutorialNotification) { this.tutorialNotification = tutorialNotification; } |
Es en este punto es donde el sporte de Spring para la inyección de dependencias entra en juego ya que como se explica en el apartado de configuración, JSF sabe
que si el la referencia del bean que se necesita inyectar no se encuentra bajo su contexto tendrá que ir a buscarlo al contexto de Spring con lo que queda resuelta
la limitación que teníamos sin hacer uso del sporte de Spring y podremos inyectar sin problemas bean que esten empaquetados en un jar fuera del proyecto web.
5. A nivel de interfaz JSF
Conociendo un poquito más como funciona el soporte de Spring en cuanto a la inyección de dependencias podemos hacer alguna cosita interesante como
por ejemplo hacer uso de un converter y publicarlo en el contexto de Spring con @Component en vez de en el contexto de JSF con @FacesConverter.
Cuando trabajamos con JSF es muy habitual trabajar con converters a nivel de interfaz de usuario. JSF2 pone a nuestra disposición la anotación @FacesConverter para
registrar nuestros propios conversores.Pero ¿que ocurre si nuestro conversor necesita inyectar un bean que no se encuentra en el contexto de JSF?. Lo que ocurre es
necesitamos hacer uso de nuestro conversor de una manera distinta para poder salvar de nuevo la misma limitación que teníamos en el punto anterior. Lo vemos a continuación:
1 2 3 4 5 6 7 8 9 10 11 12 |
@Component("tutorialConverter") public class TutorialConverter implements Converter{ private TutorialNotification tutorialNotification; @Autowired public AlertMessageConverter(TutorialNotification tutorialNotification) { this.tutorialNotification = tutorialNotification; } .... |
De esta manera estamos publicando nuestro converter en el contexto de Spring y no en el de JSF lo que nos permite inyectar como en este caso por
constructor con @Autowired referencias a objetos de negocio como servicios.
Ahora bien ¿como sabe JSF encontrar nuestro converter sino se encuentra bajo su contexto?. De nuevo entra en juego el soporte de Spring para la inyección de dependencias que hemos configurado y cuando desde la interfaz de usuario hacemos uso del converter:
1 2 3 4 5 |
... <h:outputText value="#{tuto.autentia}" converter="tutorialConverter"/> ... |
JSF busca la referencia para el identificador tutorialConverter bajo su contexto y sino lo busca en el contexto de Spring.
6. Conclusiones.
Conocer bien como funcionan las distintas piezas que conforman las aplicaciones que desarrollamos hace que tengamos menos limitaciones y más soltura a la hora
de llevarlas acabo. Asi que espero haber aportado algo de luz sobre este tema y que les pueda servir de utilidad.
Hasta próximos tutoriales.
Un saludo.
Saúl
interesante muchas gracias, estoy buscando info para saber que conviene más, si definir una arquitectura jsf-centric o spring-centric. saludos.
Excelente ayuda para mi proyecto, estaba tratando de integrar Spring3 con JSF2, y tu ayuda me sacó de un apuro. Muchas gracias.
Saludos.
Hola Saúl,
Muchas gracias por esta brebe pero importante explicación, en este momento estoy trabajando con spring frameworks y no llevo mucho tiempo lo cual hace importantisimos tus comentarios,
Bendiciones.