Sie sind auf Seite 1von 7

CDI: Patrn de diseo inyeccin aplicado al desarrollo de aplicaciones web con Java EE.

Vctor Gonzlez Chamorro


Resumen Este informe presenta el patrn de diseo inyeccin aplicado a un ejemplo prctico, utilizando como herramienta la implementacin inyeccin de dependencias y contexto o CDI (por sus siglas en ingles, Context and Dependency Injection) en Java EE. Se explica brevemente los conceptos utilizados para implementar el patrn de diseo inyeccin en Java EE. Por ltimo, se muestra como se utiliza CDI, en un ejemplo prctico que ayuda a comprender su funcionamiento, y tambin permite ver como este patrn de diseo ayuda a solucionar el problema de acoplamiento.

Introduccin En los inicios de la programacin, los programas eran mucho ms lineales y monolticos, esto hacia que seguir el flujo de ejecucin de los programas sea ms simple y predecible. A medida que fue pasando el tiempo, los mtodos de desarrollo y por ende la estructuracin del cdigo fue cambiando, de manera a facilitar ms la tarea de los programadores. Esta reestructuracin introdujo tcnicas nuevas de programacin como: popularizacin, reutilizacin de componentes, entre otras. Esto hizo que el flujo de programacin se vuelva mucho ms complejo, creando saltos de un modulo a otro, surgiendo as un nuevo problema: la dependencia o acoplamiento entre componentes. Al comienzo, este nuevo problema no era considerado lo suficientemente importante como para definir nuevos conceptos de diseo. Pero a medida que se avanzaba en el desarrollo de nuevas tcnicas de programacin, se detecto que los inconvenientes que traa este problema, eran para tener en cuenta. Es por eso que surge como paradigma un patrn de diseo que ayudara a minimizar el acoplamiento entre componentes. Este patrn se denomin Inyeccin de dependencia o DI ( por sus siglas en ingles, Dependency Injection). El resto del documento est estructurado como sigue. Una breve introduccin sobre inyeccin de dependencias en general. Luego, inyeccin de dependencias implementadas en java y algunas herramientas que provee la implementacin. Seguido a eso se presenta un ejemplo prctico, de manera a clarificar mas la teora de inyeccin de dependencias. Por ltimo, una conclusin general sobre este informe. Inyeccin de Dependencias El concepto original detrs de la inyeccin de dependencias surge de la Inversin de Control, un mtodo de programacin en donde se especifican respuestas deseadas a sucesos o solicitudes de datos concretas, dejando que algn componente externo lleve a cabo las acciones de control que se requieran en el orden necesario[1].

El concepto de inyeccin de dependencias surge especficamente al utilizar la metodologa de programacin orientada a objetos y dice que "una clase no debe configurar sus dependencias, sino estas deben ser configuradas desde afuera"[2]. Dicho de otra forma, una clase A depende de otra clase B, si A usa una instancia de B, e.g. una clase que usa un servicio de logger tiene una dependencia de ese servicio. En java, un lenguaje orientado a objetos, tambin existe la necesidad de desacoplar elementos que componen el sistema. Es por eso que se provee una herramienta que permite adoptar este patrn de diseo, con el mnimo esfuerzo posible. La herramienta es conocida como Inyeccin de dependencia y contextos o CDI ( por sus siglas en ingles, Contexts and Dependency Injection) que esta especificada en el JSR (Java Specification Requests) 299 [3]. Inyeccin de dependencias y contextos Los servicios fundamentales provedos por CDI son: de Contextos e Inyeccin de dependencias. El primero permite enlazar el ciclo de vida y la interaccin de componentes con estados a contextos con ciclos de vida bien definidos. El segundo permite inyectar componentes de manera segura en una aplicacin, incluyendo la habilidad de elegir en tiempo de ejecucin que componente inyectar. A parte de esos dos servicios principales, CDI tambin ofrece otros servicios de utilidad como: La capacidad de utilizarlo directamente en JSP (JavaServer Pages), convertirse en el patrn Decorator, e inyectar componentes, utilizar el patrn o modelo evento-notificacin, utilizar scopes (request, session and application) en aplicaciones web, definidos en los JavaServlets [3], desacoplamiento entre el cliente y el servidor permitiendo fcil modificacin del lado servidor, desacoplamiento del ciclo de vida de diferentes componentes que colaboran entre si[3], desacoplamiento de productores y consumidores utilizando paso de mensajes, entre otros.

Beans gestionados por CDI Para lograr su objetivo, CDI extiende el concepto de bean utilizado comnmente en Java. Un bean es un componente reutilizable, que tambin permite ser manipulado visualmente por una herramienta de programacin grafica, posee ciertas caractersticas especificas (Introspeccin, Customizacion, Eventos, Propiedades, Persistencia) y en general obedecen ciertas reglas de implementacin (constructor por defecto, ser Serializable, tener Introspeccin) [4]. A parte de todo esto, CDI extiende la definicin de un bean agregando que es una fuente de objetos contextuales que define el estado o la lgica de la aplicacin. Mas precisamente, un bean es tal, si el ciclo de vida de sus instancias

puede ser manejado por un contenedor acorde al ciclo de vida del contexto del modelo definido en la especificacin CDI. Los beans en CDI tienen los siguientes atributos mnimos: Un conjunto de tipos de bean Un conjunto de calificadores ( Qualifiers ) Un ambito (Scopes) Un conjunto de enlace de interceptores ( Interceptor bindings ) Una implementacion del bean

Un bean gestionado (Managed Bean) por CDI es implementado por una clase Java, que es llamada la clase bean. Una clase java es un bean gestionado si cumple las siguientes condiciones: No es nonstatic inner class Es una clase concreta o tiene la anotacin @Decorator No est declarada como bean EJB ( Enterprise JavaBeans ) Tiene el constructor apropiado, sin parmetros o con la anotacin @Inject

Beans como objetos inyectables El concepto de inyeccin en CDI de java es similar al concepto del patrn inyeccin de dependencias. Mediante el uso de anotaciones, es posible inyectar recursos y algunas otras clases de objetos, dentro de objetos gestionados por contenedores. CDI hace posible inyectar una amplia variedad de objetos e inclusive inyectarlos en objetos que no son gestionados por contenedores. A continuacin se cita una lista de objetos que pueden ser inyectados: (Prcticamente) Cualquier clase Java Beans de sesin ( Session Beans ) Recursos de Java EE: Data Sources, Java Message Service, queues, connection factories Contextos de persistencia ( Java Persistence API EntityManager Objects ) Recursos productores, e.g. data sources Objetos retornados por mtodos productores Referencias de servicios web

Utilizando Calificadores ( Qualifiers ) Si bien este informe est orientado al patrn inyeccin de dependencias, es importante mencionar brevemente a los calificadores, una caracterstica que ofrece CDI en java, y que forma parte del ejemplo prctico mostrado ms adelante. A veces es necesario proveer varias implementaciones de un tipo particular de bean. Un calificador o qualifier es una anotacin que se aplica a un bean y esto permite varias

implementaciones de distintos tipos de un bean. Ms adelante, en el ejemplo prctico se muestra un ejemplo. Ejemplo prctico del uso de CDI en Java De forma a ilustrar mejor las caractersticas que ofrece CDI, se presenta a continuacin un ejemplo prctico. Las caractersticas bsicas que se incluyen en el ejemplo son: mbitos, calificadores, inyeccin de beans, acceso a beans gestionados en una aplicacin JSF (JavaServer Faces). De manera a reducir espacio en ocasiones solo se muestran secciones relevantes del cdigo de ejemplo. Este ejemplo fue extrado de la pagina tutorial de JavaEE 6 [3]. Para ejemplo se crea una clase Java muy simple con un mtodo que retorna un string, como se puede ver en el cdigo 1. Cdigo 1
package greetings; public class Greeting { public String greet(String name) { return "Hello, " + name + "."; } }

En el cdigo 2, se puede ver la creacin de un calificador declarado como una interfaz. Vale la pena explicar brevemente que son @Retention y @Target. El primero, especifica donde puede existir esta anotacin, en este caso en tiempo de ejecucin (RUNTIME). El segundo define a que tipos de elementos Java se pueden aplicar el calificador, en este caso son: TYPE, METHOD, FIELD, PARAMTER. Cdigo 2
package greetings; import import import import import static static static static static java.lang.annotation.ElementType.FIELD; java.lang.annotation.ElementType.METHOD; java.lang.annotation.ElementType.PARAMETER; java.lang.annotation.ElementType.TYPE; java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @interface Informal {}

Luego, este calificador podr ser utilizado por un bean que extiende la funcionalidad de otro bean padre. Para este ejemplo en particular, transformado el string retornado por el mtodo greet. En el cdigo 3 se puede ver como se utiliza el nuevo calificador creado. Cdigo 3 ....
@Informal public class InformalGreeting extends Greeting { public String greet(String name) { return "Hi, " + name + "!"; } }

..... Para hacer accesible el estado de un bean gestionado, se necesita agregar mtodos getters y setters [5] para cada estado. En el cdigo 4 se muestra la implementacin de la clase Printer que ser un bean gestionado y a la que se le inyecta el bean Greeting. Cdigo 4 ...
public class Printer { @Inject @Informal Greeting greeting; private String name; private String salutation; public void createSalutation() { this.salutation = greeting.greet(name); } public String getSalutation() { return salutation; } public void setName(String name) { this.name = name; } public String getName() { return name; } }

... Como se haba mencionado antes, este ejemplo es un aplicacin que utiliza JSF, por eso en el cdigo 5 se muestra la ultima parte para completar que es la plantilla web Facelets [3].

Cdigo 5
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"> <ui:composition template="/template.xhtml"> <ui:define name="title">Simple Greeting</ui:define> <ui:define name="head">Simple Greeting</ui:define> <ui:define name="content"> <h:form id="greetme"> <p><h:outputLabel value="Enter your name: " for="name"/> <h:inputText id="name" value="#{printer.name}"/></p> <p><h:commandButton value="Say Hello" action="#{printer.createSalutation}"/></p> <p><h:outputText value="#{printer.salutation}"/> </p> </h:form> </ui:define> </ui:composition> </html>

Al visualizar el facelets como pagina web, tenemos un formulario que pide al usuario que ingrese su nombre. Tambin, hay un botn, que al hacer clic, define la accin que va tener este formulario. Las partes ms relevantes de este cdigo estn resaltadas en negrita y se explica a continuacin. La accin a llevar a cabo esta definida por createSalutation, el mtodo de la clase Printer que es un bean gestionado como se haba visto anteriormente. Este mtodo, por medio de una inyeccin, llama a mtodo greet de la clase Greetings. El texto mostrado en el formulario est definido por el valor del Greeting inyectado, que en este caso es InformalGreeting Como se puede ver, el valor retornado puede ser modificado fcilmente cambiando la inyeccin de Greeting en Printer. Salida

Conclusiones Se ha visto que, si bien los nuevos paradigmas de programacin pueden ayudar a solucionar mejor la mayora de los problemas, estos no vienen solo con ventajas. Tambin, traen consigo problemas que son consecuencias de la metodologa adoptada. Si bien estos problemas al comienzo pueden ignorados, a la larga pueden generar mayores dolores de cabeza, tal vez en el mantenimiento o modificacin de un sistema. Es por eso que se ha detectado e implementado como mediada para solucionar el problema, el patrn de inyeccin de dependencias. En Java se implementa la inyeccin de dependencias por medio de CDI, un framework que permite una implementacin sencilla de este patrn de diseo. Si bien CDI posee varias herramientas que ayudan al desarrollador, tiene como una de sus partes claves el patrn de inyeccin de dependencias. Esto, permite un desarrollo con mayor desacoplamiento de componentes, sin introducir muchas complejidades en el cdigo. Como es sabido, una buena prctica de desarrollo de sistemas, es que este tenga un bajo acoplamiento entre sus componentes. Para lograr esto, tal vez, se tenga que trabajar ms al comienzo del desarrollo de una aplicacin, ya que se deben definir los beans que sern finalmente gestionados y/o inyectados. Pero, a la larga, se logra que el sistema pueda ser fcilmente modificable, el cdigo menos complejo y por ende mas mantenible. Si se pueden ganar las caractersticas citadas, tal vez, sea valido trabajar ms al comienzo para facilitar la tarea en etapas posteriores.

Bibliografa [1] https://blog.itu.dk/MMAD-F2013/files/2013/02/3-inversion-of-control-containers-and-thedependency-injection-pattern.pdf [2] http://martinfowler.com/articles/injection.html [3] http://docs.oracle.com/javaee/6/tutorial/doc/gjbls.html [4] http://www.sc.ehu.es/sbweb/fisica/cursoJava/applets/javaBeans/fundamento.htm [5] http://gl-epn-programacion-ii.blogspot.com/2010/03/setters-getters.html

Das könnte Ihnen auch gefallen