Integración de Spring JSF: ¿cómo inyectar un componente/servicio de Spring en JSF managed bean?
Entiendo que un bean administrado funciona como un controlador, porque su única tarea es "vincular" la capa de vista con el Modelo.
Para usar un bean como un bean administrado debo declarar @ManagedBean
anotación, haciendo eso puedo comunicar JSF con bean directamente.
Si quiero inyectar algún componente (de Spring) en este ManagedBean tengo dos maneras posibles:
Elija la propiedad en ManagedBean (como "BasicDAO dao") y declare
@ManagedProperty(#{"basicDAO"})
encima de la propiedad. Haciéndolo, estoy inyectar el frijol"basicDAO"
desde la primavera en el frijol manejado.Declarado @ Controller en la clase ManagedBean, entonces tendré
@ManagedBean
y@Controller
anotaciones, todas juntas. Y en propiedad"BasicDAO dao"
debo usar@Autowired
desde la Primavera.
, Es mi entendimiento correcto?
3 answers
Hay otra forma de usar frijoles administrados por Spring en frijoles administrados por JSF simplemente extendiendo su frijol JSF desde SpringBeanAutowiringSupport
y Spring manejará 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.
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 22:15:50
@ManagedBean
vs @Controller
En primer lugar, debe elegir un marco para administrar sus frijoles. Debe elegir JSF o Spring (o CDI) para administrar sus frijoles. Mientras que las siguientes obras, 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 en realidad se usaría en EL cuando usted lo hace referencia como #{someBean}
. Si usted tiene el SpringBeanFacesELResolver
registrado en faces-config.xml
, entonces sería el administrado por Spring, no el administrado por JSF. Si no tienes eso, entonces sería el administrado por JSF.
También, cuando se declara un ámbito específico de frijol administrado por JSF, como @RequestScoped
, @ViewScoped
, @SessionScoped
o @ApplicationScoped
del paquete javax.faces.*
, solo será reconocido y utilizado por @ManagedBean
. No será entendido por @Controller
ya que espera su propia anotación @Scope
. El valor predeterminado es singleton (ámbito de 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 administrado por Spring, no el bean con ámbito de vista administrado por JSF.
@ManagedProperty
vs @Autowired
El @ManagedProperty
específico de JSF funciona solo en frijoles administrados por JSF, es decir, cuando se está utilizando @ManagedBean
. El @Autowired
específico para la primavera solo funciona en frijoles administrados en primavera, es decir, cuando se usa @Controller
. Por debajo de los enfoques son menos o más equivalentes y no puede ser mixto:
@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 usted tiene la SpringBeanFacesELResolver
registered in faces-config.xml
as per the javadoc ,
<application>
...
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
Y por lo tanto puede hacer referencia a los frijoles administrados de primavera en EL vía #{springBeanName}
, entonces puede simplemente 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, inyectar un frijol administrado por JSF a través de @Autowired
, no es compatible de ninguna manera. Sin embargo, puede usar @Autowired
en un frijol administrado por JSF cuando manualmente registre la instancia de JSF managed bean en el contexto Spring autowirable como se muestra a continuación. Ver 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
Spring's @Scope
tiene soporte limitado para los ámbitos JSF. No hay equivalente para JSF @ViewScoped
. Básicamente, crearía sus propios alcances o se limitaría a registrar manualmente la instancia de JSF managed bean en el contexto autowirable de Spring, como se muestra arriba.
Y, desde el otro lado, Spring WebFlow fue tomado en JSF 2.2 a través de una nueva anotación @FlowScoped
. Entonces, si ya está en JSF 2.2, no necesariamente necesita usar Spring WebFlow si solo desea el ámbito de 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 un @ManagedBean
puede hacer referencia a un @Named
bean. Por otro lado, @ManagedProperty
no funciona dentro de un frijol @Named
.
El propósito de CDI es unificar todos los diferentes marcos de gestión de bean en una sola especificación/inteface. Spring podría haber sido una implementación completa de CDI, pero optaron por implementarla solo parcialmente (solo JSR-330 javax.inject.*
está soportado, pero JSR-299 javax.enterprise.context.*
no). Véase también Soporte de primavera CDI? y este tutorial.
JSF se moverá a CDI para la gestión de frijol y deprecate @ManagedBean
y amigos en una versión futura.
Véase también:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:44
La forma fácil de hacerlo es a través de XML. Usé @Component
en ya hecho jsf managed bean pero @Autowired
no funcionó porque managed bean ya estaba allí en faces-config.XML. Si es obligatorio mantener esa definición de frijol administrado junto con su propiedad administrada en el archivo xml, se sugiere agregar el frijol de primavera como otra propiedad administrada dentro de la etiqueta de frijol administrado. Aquí el frijol de primavera se define en spring-config.xml (puede ser autowired en algún lugar alternativamente). por favor refiérase
https://stackoverflow.com/a/19904591/5620851
Editado por mí. Sugiero implementarlo por completo a través de annotation @ Managed y @ Component o a través de xml para ambos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:25