JavaServer Faces (JSF) con Spring

1. Información general

En este artículo, veremos una receta para acceder a los beans definidos en Spring desde un bean administrado JSF y una página JSF, con el fin de delegar la ejecución de la lógica empresarial a los beans Spring.

Este artículo asume que el lector tiene un conocimiento previo de JSF y Spring por separado. El artículo se basa en la implementación de JSF de Mojarra.

2. En primavera

Tengamos el siguiente bean definido en Spring. El bean UserManagementDAO agrega un nombre de usuario a un almacén en memoria, y está definido por la siguiente interfaz:

public interface UserManagementDAO { boolean createUser(String newUserData); }

La implementación del bean se configura utilizando la siguiente configuración de Java:

public class SpringCoreConfig { @Bean public UserManagementDAO userManagementDAO() { return new UserManagementDAOImpl(); } }

O usando la siguiente configuración XML:

Definimos el bean en XML y registramos CommonAnnotationBeanPostProcessor para asegurarnos de que se recoja la anotación @PostConstruct .

3. Configuración

Las siguientes secciones explican los elementos de configuración que permiten la integración de los contextos Spring y JSF.

3.1. Configuración de Java sin web.xml

Al implementar WebApplicationInitializer, podemos configurar mediante programación el ServletContext. La siguiente es la implementación onStartup () dentro de la clase MainWebAppInitializer :

public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SpringCoreConfig.class); sc.addListener(new ContextLoaderListener(root)); }

El AnnotationConfigWebApplicationContext Bootstraps el contexto Spring'g y agrega los granos mediante el registro de la SpringCoreConfig clase.

De manera similar, en la implementación de Mojarra hay una clase FacesInitializer que configura el FacesServlet. Para utilizar esta configuración basta con ampliar el FacesInitializer. La implementación completa de MainWebAppInitializer, ahora es la siguiente:

public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer { public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SpringCoreConfig.class); sc.addListener(new ContextLoaderListener(root)); } }

3.2. Con web.xml

Comenzaremos configurando ContextLoaderListener en el archivo web.xml de la aplicación:

  org.springframework.web.context.ContextLoaderListener  

Este oyente es responsable de iniciar el contexto de la aplicación Spring cuando se inicia la aplicación web. Este oyente buscará un archivo de configuración de primavera llamado applicationContext.xml por defecto.

3.3. faces-config.xml

Ahora configuramos SpringBeanFacesELResolver en el archivo face-config.xml :

org.springframework.web.jsf.el.SpringBeanFacesELResolver

Un resolutor EL es un componente conectable compatible con el marco JSF, lo que nos permite personalizar el comportamiento del tiempo de ejecución JSF al evaluar expresiones de Lenguaje de expresión (EL). Este resolutor EL permitirá que el tiempo de ejecución JSF acceda a los componentes Spring a través de expresiones EL definidas en JSF.

4. Acceder a Spring Beans en JSF

En este punto, nuestra aplicación web JSF está preparada para acceder a nuestro bean Spring desde un bean de respaldo JSF o desde una página JSF.

4.1. Desde un Backing Bean JSF 2.0

Ahora se puede acceder al bean Spring desde un bean de respaldo JSF. Dependiendo de la versión de JSF que esté ejecutando, existen dos métodos posibles. Con JSF 2.0, usa la anotación @ManagedProperty en el bean administrado JSF.

@ManagedBean(name = "registration") @RequestScoped public class RegistrationBean implements Serializable { @ManagedProperty(value = "#{userManagementDAO}") transient private IUserManagementDAO theUserDao; private String userName;
 // getters and setters }

Tenga en cuenta que el captador y el definidor son obligatorios cuando se utiliza @ManagedProperty.

Ahora, para afirmar la accesibilidad de un bean Spring desde un bean administrado, agregaremos el método createNewUser () :

public void createNewUser() { FacesContext context = FacesContext.getCurrentInstance(); boolean operationStatus = userDao.createUser(userName); context.isValidationFailed(); if (operationStatus) { operationMessage = "User " + userName + " created"; } } 

La esencia del método es usar el bean userDao Spring y acceder a su funcionalidad.

4.2. Desde un Bean de respaldo en JSF 2.2

Otro enfoque, válido solo en JSF2.2 y superior, es usar la anotación @Inject de CDI . Esto es aplicable a beans administrados por JSF (con la anotación @ManagedBean ) y beans administrados por CDI (con la anotación @Named ).

De hecho, con una anotación CDI, este es el único método válido para inyectar el bean:

@Named( "registration") @RequestScoped public class RegistrationBean implements Serializable { @Inject UserManagementDAO theUserDao; }

Con este enfoque, el getter y setter no son necesarios. También tenga en cuenta que la expresión EL está ausente.

4.3. Desde una vista JSF

El método createNewUser () se activará desde la siguiente página JSF:

Para renderizar la página, inicie el servidor y navegue hasta:

//localhost:8080/jsf/index.jsf

También podemos usar EL en la vista JSF para acceder al bean Spring. Para probarlo basta con cambiar la línea número 7 de la página JSF introducida previamente a:

Here, we call the createUser method directly on the Spring DAO, passing the bind value of the userName to the method from within the JSF page, circumventing the managed bean all together.

5. Conclusion

We examined a basic integration between the Spring and JSF contexts, where we’re able to access a Spring bean in a JSF bean and page.

It’s worth noting that while the JSF runtime provides the pluggable architecture that enables the Spring framework to provide integration components, the annotations from the Spring framework cannot be used in a JSF context and vice versa.

Lo que esto significa es que no podrá usar anotaciones como @Autowired o @Component, etc. en un bean administrado por JSF, o usar la anotación @ManagedBean en un bean administrado por Spring. Sin embargo, puede usar la anotación @Inject tanto en un bean administrado JSF 2.2+ como en un bean Spring (porque Spring admite JSR-330).

El código fuente que acompaña a este artículo está disponible en GitHub.