Skip to content

Integración Spring JSF: ¿cómo inyectar un componente / servicio Spring en un bean administrado JSF?

Deseamos compartirte la mejor información que hemos encontrado on line. Queremos que te resulte útil y si quieres comentarnos alguna mejora hazlo libremente.

Solución:

@ManagedBean vs @Controller

En primer lugar, debes elegir uno marco para administrar sus frijoles. Debe elegir JSF o Spring (o CDI) para administrar sus beans. Si bien lo siguiente funciona, es fundamentalmente incorrecto:

@ManagedBean // JSF-managed.
@Controller // Spring-managed.
public class BadBean 

Terminas con dos instancias completamente separadas de la misma clase de bean administrada, una administrada por JSF y otra administrada por Spring. No está directamente claro cuál Realmente ser utilizado en EL cuando se hace referencia a él como #someBean. Si tienes el SpringBeanFacesELResolver registrado en faces-config.xml, entonces sería el administrado por Spring, no el administrado por JSF. Si no tiene eso, entonces sería el administrado por JSF.

Además, cuando declara un alcance específico de bean administrado JSF, como @RequestScoped, @ViewScoped, @SessionScoped o @ApplicationScoped de javax.faces.* paquete, sólo será reconocido y utilizado por @ManagedBean. No será entendido por @Controller como espera lo suyo @Scope anotación. Este valor predeterminado es singleton (alcance de la aplicación) cuando está ausente.

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
@Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean 

Cuando hace referencia al bean anterior a través de #someBean, devolvería el bean con ámbito de aplicación gestionado por Spring, no el bean con ámbito de vista gestionado por JSF.


@ManagedProperty vs @Autowired

El específico de JSF @ManagedProperty funciona solo en beans administrados por JSF, es decir, cuando está usando @ManagedBean. El específico de primavera @Autowired funciona solo en beans administrados por Spring, es decir, cuando está usando @Controller. Los siguientes enfoques son menos o más equivalentes y no se pueden mixed:

@ManagedBean // JSF-managed.
@RequestScoped // JSF-managed scope.
public class GoodBean 

    @ManagedProperty("#springBeanName")
    private SpringBeanClass springBeanName; // Setter required.

@Component // Spring-managed.
@Scope("request") // Spring-managed scope.
public class GoodBean 

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

Tenga en cuenta que cuando tenga el SpringBeanFacesELResolver registrado en faces-config.xml según el javadoc,


    ...
    org.springframework.web.jsf.el.SpringBeanFacesELResolver

y, por lo tanto, puede hacer referencia a los beans administrados por Spring en EL a través de #springBeanName, entonces puede hacer referencia a ellos en @ManagedProperty también, ya que básicamente establece el resultado evaluado de la expresión EL dada. Al revés, inyectando un bean administrado JSF a través de @Autowired, no es compatible de ninguna manera. Sin embargo, puedes usar @Autowired en un bean administrado por JSF cuando extiende su bean desde SpringBeanAutowiringSupport. Esto registrará automáticamente la instancia de bean administrada por JSF en el contexto autorizable de Spring durante la invocación del constructor, lo que significa que todo @Autowired estará disponible en @PostConstruct y después.

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport implements Serializable 

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() 
        // springBeanName is now available.
    

O cuando su arquitectura no permite extender beans desde una clase base diferente, siempre puede registrar manualmente la instancia de bean administrada JSF en el contexto de Spring autowable como se muestra a continuación. Vea también Cómo integrar JSF 2 y Spring 3 (o Spring 4) muy bien para el truco.

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean implements Serializable 

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() 
        FacesContextUtils
            .getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
            .getAutowireCapableBeanFactory().autowireBean(this);

        // springBeanName is now available.
    


@XxxScoped vs @Scope

Muelles @Scope tiene soporte limitado para ámbitos JSF. No hay equivalente para JSF @ViewScoped. Básicamente, cultivaría sus propios alcances o se limitaría a registrar manualmente la instancia de bean administrada JSF en el contexto de Spring Autowable como se muestra arriba.

Y, desde el otro lado, Spring WebFlow fue asumido en JSF 2.2 a través de un nuevo @FlowScoped anotación. Entonces, si ya está en JSF 2.2, entonces no necesariamente necesita usar Spring WebFlow si solo desea el alcance del flujo.


CDI – tratando de unificarlo todo

Desde Java EE 6, CDI se ofrece como alternativa estándar a Spring DI. Tiene respectivamente @Named y @Inject anotaciones para esto y también su propio conjunto de ámbitos. No estoy seguro de cómo interactúa con Spring ya que no uso Spring, pero @Inject funciona dentro de un @ManagedBean, y @ManagedProperty dentro de una @ManagedBean puede hacer referencia a un @Named frijol. Por otra parte, @ManagedProperty no funciona dentro de un @Named frijol.

El propósito de CDI es unificar todos los diferentes marcos de gestión de beans en una sola especificación / interfaz. Spring podría haber sido una implementación completa de CDI, pero eligieron implementarla solo parcialmente (solo JSR-330 javax.inject.* es compatible, pero JSR-299 javax.enterprise.context.* no). Consulte también ¿Spring admitirá CDI? y este tutorial.

JSF se moverá a CDI para la gestión de beans y se desaprobará @ManagedBean y amigos en una versión futura.

@Named // CDI-managed.
@ViewScoped // CDI-managed scope.
public class BetterBean implements Serializable 

    @Inject
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() 
        // springBeanName is now available.
    

Ver también:

  • ¿Cuándo es necesario o conveniente utilizar Spring o EJB3 o todos juntos?
  • Capa de servicio JSF
  • ¿Backing beans (@ManagedBean) o CDI Beans (@Named)?
  • Usando JSF como tecnología de vista de Spring MVC
  • ¿Cómo instalar y usar CDI en Tomcat?

Hay otra forma de usar beans administrados por Spring en beans administrados por JSF simplemente extendiendo su bean JSF de SpringBeanAutowiringSupport y Spring se encargará de la inyección de dependencia.

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport 

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    // springBeanName is now available.

Te invitamos a añadir valor a nuestro contenido informacional aportando tu veteranía en las referencias.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *