Inyeccion de Dependencias con Spring Framework
Hola comunidad Java.
Tengo un problemita al Inyectar Dependencias con spring framework, y he buscado por la web y nada que resulta.
ESPERO PUEDAN AYUDARME... GRACIAS!!
Estoy realizando un proyecto y uso Spring y Hibernate.
El proyecto se compone de:
1) vista JSF
2) manage Bean
3) Service
4) DAO
5) POJO
Solo que a la hora de acceder al bean, manda un Exception de tipo NULL,
pero es que el service desde el inicio viene nulo, el codigo es el siguiente
------------- MBean -----------
package rip.clases.MBean;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import rip.clases.constantes.RipConstantes;
import rip.clases.service.UsuarioService;
import rip.clases.VO.UsuarioVO;
@ManagedBean(name = "admUsuarioMBean")
@SessionScoped
public class AdmUsuarioMBean extends AdmComunMBean{
@ManagedProperty(value = RipConstantes.SRV_USUARIO_INJ)
private UsuarioService usuarioService;
private String nombreUsuario;
public AdmUsuarioMBean() {
super();
}
@PostConstruct
@Override
public void inicializar(){
listaDatos = new ArrayList();
}
@Override
public void buscar() {
List nvaListaUsuarioVO;
try{
nvaListaUsuarioVO = usuarioService.consultarUsuarioPorParam(nombreUsuario);
this.listaDatos = nvaListaUsuarioVO;
System.out.println(this.listaDatos);
}catch(Exception ex){
ex.printStackTrace();
}
}
public UsuarioService getUsuarioService() {
return usuarioService;
}
public void setUsuarioService(UsuarioService usuarioService) {
this.usuarioService = usuarioService;
}
public String getNombreUsuario() {
return nombreUsuario;
}
public void setNombreUsuario(String nombreUsuario) {
this.nombreUsuario = nombreUsuario;
}
}
---------------------- Service -------------
package rip.clases.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import rip.clases.builder.UsuarioBuilder;
import rip.clases.DAO.UsuarioDao;
import rip.clases.PO.UsuarioPO;
import rip.clases.VO.UsuarioVO;
@Service(value="usuarioService")
public class UsuarioServiceImpl implements UsuarioService{
@Autowired
private UsuarioDao usuarioDao;
@Transactional
@Override
public List consultarUsuarioPorParam(String nombreUsuario) throws Exception {
List listaUsuarioVO = null;
try{
List listaUsuarioPO = usuarioDao.consultarUsuarioPorParam(nombreUsuario);
listaUsuarioVO = UsuarioBuilder.conviertePOJOtoVO(listaUsuarioPO);
}catch(Exception ex){
throw new Exception(ex.getMessage(), ex);
}
return listaUsuarioVO;
}
}
----------------- applicationContext --------------------
<?xml version="1.0" encoding="UTF-8"?>
">
com.mysql.jdbc.Driver
URL BASE DE DATOS
USERNAME
PASSWORD
org.hibernate.dialect.MySQLDialect
rip.clases.PO.UsuarioPO
- Inicie sesión o regístrese para enviar comentarios
Prueba inyectandolo tu
Prueba inyectandolo tu servicio dentro de tu MB de esta forma:
@ManagedProperty(value = "#{usuarioService}")
private UsuarioService usuarioService;
Ademas, dentro de tus faces-config debes tener esto:
org.springframework.web.jsf.el.SpringBeanFacesELResolver
De esta forma puedes inyectar beans de spring en el contexto de JSF
Te recomiendo que el scope de tus MB sean de vista y no de session, al menos que requieras que tus beans vivan todo el tiempo que dure la session del usuario firmado.
Saludos
Otra cosa
No inyectes usando la anotación: @Autowired, es costoso para Spring. Existen buenas practicas dentro del manual de referencia de Spring que te explican como hacerlo.
saludos.
Otra cosa
Cuando crees un post encierra el codigo fuente entre las etiquetas code y /code para que tu codigo sea mas legible.
saludos
No inyectes usando la anotación: @Autowired, es costoso
Al ver este comentario, me preguntaba por que es costoso @Autowired, Si podrias explicar esto para ser mas puntuales.
Saludos
¿Cuáles son las buenas prácticas?
¿Porqué usar @Autowired es costoso? ¿Qué recomiendas usar?
Autowired?
Yo el único pero que le pongo a
es que no es estándar sino algo de Spring; a partir de que salió
como parte de JSE ya es preferible usar esa anotación, además que con @Resource puedes indicar el nombre del bean, mientras que con @Autowired necesitas agregar otra anotación @Qualified o algo así se llamaba para indicar el bean (eso es necesario cuando tienes varios beans que son candidatos para inyectarse ahí; Spring no decide por ti, sino te pide que especifiques cuál quieres, ya sea con anotaciones o XML o algo).
Pero no había escuchado eso de que sea costoso. A menos que te refieras al proceso adicional de analizar todos los beans definidos en el application context para ver cuáles tienen esa anotación, pero entonces la solución para evitar ese tiempo adicional de análisis es NO poner en el XML
porque si lo tienes, entonces el análisis se realiza aunque ningún componente tenga la anotación Autowired.
Buenas practicas
Cuando empece a estudiar Spring, en algun apartado de la documentacion explicaban las diferentes formas de inyectar un bean, recomendaban inyectar por setter o por el constructor, ya que de esta manera se evitaban realizar instropeccion a las clases. Yo conclui en que esto era costoso y por eso lo evito en mis aplicaciones. Les paso un link a la pagina de "Dos Ideas" con algunas buenas practicas a la hora de usar Spring:
Aunque como lo comenta Enrique, el autoscaneo de las clases al final de cuentas realiza un barrido a las clases anotadas para saber que cosas va a inyectar y esto se supone lo realiza una sola ves cuando se carga el contexto de Spring, entonces no debe existir mucha diferencia entre anotarlas con Autowired o no.
Saludos.
Gracias, es de mucha utilidad
Gracias, es de mucha utilidad los comentarios
No es muy claro el porqué...
Los nombres de las propiedades de la clase InvasorService son usadas para buscar instancias de beans en el contenedor. El uso de Autowiring nos salva de tipear mucho código. De todas formas, nunca deberíamos utilizar Autowiring en una aplicación real porque perjudicamos la legibilidad de nuestro archivo de configuración y la mantenibilidad del mismo. Parece una buena idea hacer que nuestros archivos XML de configuración sean pequeños, pero esto aumenta en gran medida la complejidad de comprensión de la solución.
Spring también nos permite mezclar las dos técnicas (Autowiring y no-autowiring), pero con esto solamente lograríamos hacer mucho más confusa la configuración.
- No vi que dijera que por rendimiento, dice que por complejidad para entender el código. En el texto no habla de una anotación, es una propiedad del xml.
En mi opinión prefiero anotaciones a un archivo xml muy grande.