La inyección de dependencia es uno de los conceptos que ya hemos abordado a nivel de EJBs en donde habitualmente un Servlet accede a un EJB vía inyección de dependencia usando la anotación @EJB
Vamos a ver el código del EJB Interface MensajeLocal
package com.arquitecturajava; import javax.ejb.Local; @Local public interface MensajeLocal { public String hola(); }
EJB Implementación
package com.arquitecturajava; import javax.ejb.Stateless; @Stateless public class Mensaje implements MensajeLocal { @Override public String hola() { return "accediendo al EJB de hola"; } }
Servlet
import java.io.IOException; import java.io.PrintWriter; import javax.ejb.EJB; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletCDI") public class ServletCDI extends HttpServlet { private static final long serialVersionUID = 1L; @EJB MensajeLocal mensaje; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter pw= response.getWriter(); pw.println(mensaje.hola()); pw.close(); } }
Java EE 5 Limitaciones
Este código funciona perfectamente a nivel de Java EE 5 .Sin embargo tiene una serie de limitaciones entre ellas que no podemos inyectar una clase como la siguiente .
package com.arquitecturajava; public class UtilidadBean { public String hola() { return "Hola desde la utilidad"; } }
Java EE 5 no permite la inyección de dependencias a nivel de POJOs, solo a nivel de EJBs.
Java EE 6 (Java y CDI)
A partir de la versión 6 de Java EE podemos hacer uso de CDI (Context Dependency Inyection) que es la JSR que nos permite definir inyección de dependencias tanto para EJBs como para POJOs .De esta forma podremos construir el Servlet que utilizando la anotacion @Inject sea capaz de inyectar una clase de tipo POJO.
package com.arquitecturajava; import java.io.IOException; import java.io.PrintWriter; import javax.ejb.EJB; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletCDI") public class ServletCDI extends HttpServlet { private static final long serialVersionUID = 1L; @EJB MensajeLocal mensaje; @Inject UtilidadBean mensajeUtilidad; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter pw= response.getWriter(); pw.println(mensaje.hola()); pw.println(mensajeUtilidad.hola()); pw.close(); } }
Una vez inyectadas las dependencias si invocamos la URL del servlet el resultado será el siguiente.
Beans.xml
Para que todo esto funcione correctamente deberemos añadir el fichero de beans.xml (JSR 330) a la carpeta WEB-INF. Sino la aplicación no será capaz de inyectar correctamente las dependencias.
El contenido de este fichero esta vacío para un ejemplo tan sencillo pero el fichero es obligatorio .
<?xml version="1.0"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd"/>
EJBs y @Inject
Hemos usado @Inject para inyectar POJOS pero lo podríamos utilizar de igual manera para inyectar EJBs
import java.io.IOException; import java.io.PrintWriter; import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/ServletCDI") public class ServletCDI extends HttpServlet { private static final long serialVersionUID = 1L; @Inject MensajeLocal mensaje; @Inject UtilidadBean mensajeUtilidad; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter pw= response.getWriter(); pw.println(mensaje.hola()); pw.println(mensajeUtilidad.hola()); pw.close(); } }
De esta forma JEE 6 nos simplifica el uso de anotaciones
Excelente artículo, como siempre: breve, conciso y asequible.
gracias 🙂
Hola , muy buen post como siempre,
Una pregunat esto también funciona para hacer @inject a un EntityManager o es necesario hacerlo con el @PersistenceContext
Saludos
Si es posible pero la anotación de @PersistenceContext permite hacer cosas mas complejas que @inject que es muy genérica. Por ejemplo a nivel de EJB permite extender el contexto
Hola, es posible inyectar en un POJO un bean usando la interface local, para evitar el lookup a través de la remota?
No te entiendo muy bien la pregunta normalmente un EJB permite la inyeccion de otro EJB pero no en el caso de un EJB Remoto , salvo en la situación de que esten en la misma JVM que a veces hay optimizaciones
Mi inquietud es: pretendo invocar desde un POJO un bean de sesión y ejecutar operaciones sobre la base de datos. Actualmente lo logro haciendo un lookup directamente con el JNDI de la interface remota del bean. Hay alguna forma que pueda injectar el bean de sesión en un POJO con acceso local?
Los beans están en el mismo EAR del POJO.
Convierte al Pojo en un Stateless Session Bean , no debería dar problema
Lo primero saludar y decir que el post me parece muy interesante.
Dicho esto, entiendo que para los EJBs dado que el control de instancias (entre otras muchas cosas) lo maneja el propio contenedor de EJB, el uso de la inyección de dependencias es muy cómodo y de uso casi obligado.
La duda me surge con el @Inject de la clase POJO ya que no llego a entender que ventajas aporta frente a instanciar directamente el objecto con “UtilidadBean mensajeUtilidad = new mensajeUtilidad();”
Buenas Jesus
La inyección de dependencia aporta “flexibilidad” ya que al no ser tu como desarrollador el que define que tipo de objeto se instancia se podrián inyectar otras dependencias que no fueran exactamente UtilidadBean . Por ejemplo alguna clase hija que varíe el “comportamiento” . En mi libro viene explicado un poco mas a detalle
Una de la gran ventaja significativa que tiene la inyección de dependencia es que se define el Scoped que tiene el pojo y en tiempo de ejecución el mismo se libera sin hacer gran uso de la memoria.
Un gran aporte que trae consigo el uso de CDI es el aprovechamiento de la memoria y la sucesión de los ManagedBean JSF a partir de la version 2.1 de hecho el mismo es parte del estandar de JavaEE 7
gracias por el aporte 🙂