Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

unidades:10_servidor:04_inyecciondependencias [2014/08/30 23:18]
admin creado
unidades:10_servidor:04_inyecciondependencias [2014/09/03 11:56] (actual)
admin [La solución]
Línea 1: Línea 1:
 ====== 10.4 Inyección de dependencias ====== ====== 10.4 Inyección de dependencias ======
 +La inyección de dependencias (en inglés Dependency Injection, DI) es un patrón de diseño sencillo de usar aunque quizás resulte algo muy novedoso para algunas personas. ​
 +
 +
 +===== El problema =====
 +La inyección de dependencias intenta resolver el problema que hay en el código del ejemplo de JSON de hace 2 temas:
 +
 +<sxh java;​highlight:​ [5]>
 +public class Main {
 + 
 + 
 +    public static void main(String[] args) {
 +        JsonTransformer jsonTransformer=new JsonTransformerImplJackson();​
 +         
 +        Usuario usuario=new Usuario("​Alberto Tortosa","​alberto_tortosa@gmail.com",​91);​
 +         
 +        String jsonUsuario=jsonTransformer.toJson(usuario);​
 +         
 +        System.out.println(jsonUsuario);​
 +         
 +         
 +        Usuario newUsuario=(Usuario) jsonTransformer.fromJson(jsonUsuario,​ Usuario.class);​
 +           
 +        System.out.println("​Nombre:"​+newUsuario.getNombre());​
 +        System.out.println("​E-Mail:"​+newUsuario.getEmail());​
 +        System.out.println("​Edad:"​+newUsuario.getEdad());​
 +         
 +    }
 +     
 +}
 +</​sxh>​
 +
 +¿Cual es el problema que hay en ese código? ¡Si lo hicimos muy bien añadiendo el interfaz para abstraernos de saber nada de Jackson! Pero , ¿Seguro que no sabemos nada de Jackson? Si te fijas en la línea 5 verás que aparece la palabra "​Jackson"​ en la clase ''​JsonTransformerImplJackson''​. ​
 +
 +El problema es que tenemos dentro del código la implementación que usamos del interfaz y si usamos el interfaz para no saber nada sobre su implementación es un sin sentido que tengamos en el propio código una referencia a la implementación. Además is quisiéramos cambiar la implementación deberíamos ir por todo el código buscando donde se usa para cambiarlo.
 +
 +===== La solución =====
 +La solución a todo ésto es la **Inyección de Dependencias** que evita que nuestro código tenga referencias a las implementaciones que usamos.
 +
 +Vamos a modificar el controlador ''​UsuarioController ''​ del tema anterior de forma que usemos ''​JsonTransformer'':​
 +
 +<sxh java;​highlight:​ [6];​title:​UsuarioController.java>​
 +@Controller
 +public class UsuarioController {
 +
 +    @RequestMapping(value = {"/​Usuario"​})
 +    public void prueba(HttpServletRequest httpRequest,​ HttpServletResponse httpServletResponse) throws IOException {
 +        JsonTransformer jsonTransformer=new JsonTransformerImplJackson();​
 +        ​
 +        Usuario usuario=new Usuario("​Alberto Tortosa","​alberto_tortosa@gmail.com",​91);​
 +        String jsonUsuario=jsonTransformer.toJson(usuario);​
 +        ​
 +        httpServletResponse.getWriter().println(jsonUsuario);​
 +    }
 +}
 +</​sxh>​
 +Vemos que ahora el controlador en vez de mostrar en la página web el texto "Hola mundo" retornara el JSON:
 +  {"​nombre":"​Alberto Tortosa","​email":"​alberto_tortosa@gmail.com","​edad":​91}
 +
 +Pero seguimos teniendo el mismo problema que antes. ¿Como lo resolvemos? Como ya tenemos configurado Spring en esta aplicación , nos va a resultar muy sencillo. Simplemente vamos a hacer unas pequeñas modificaciones:​
 +  * Decirle a Spring cual es la clase con la implementación de ''​JsonTransformer''​
 +  * Quitar la referencia a la implementación del controlador
 +  * Indicar a Spring que inyecte la implementación en el controlador.
 +
 +Vamos a modificar el fichero ''​applicationContext.xml''​
 +<sxh xml;​highlight:​ [12];​title:​applicationContext.xml>​
 +<?xml version="​1.0"​ encoding="​UTF-8"?>​
 +<beans xmlns="​http://​www.springframework.org/​schema/​beans"​
 +       ​xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​
 +       ​xmlns:​context="​http://​www.springframework.org/​schema/​context"​
 +       ​xsi:​schemaLocation="​
 +       ​http://​www.springframework.org/​schema/​beans ​  ​http://​www.springframework.org/​schema/​beans/​spring-beans-4.0.xsd
 +       ​http://​www.springframework.org/​schema/​context http://​www.springframework.org/​schema/​context/​spring-context-4.0.xsd
 +">
 + 
 +    <​context:​annotation-config/>​
 + 
 +    <bean class="​es.cursoangularjs.inyecciondependencias.json.JsonTransformerImplJackson"​ />
 +    ​
 +</​beans>​
 +</​sxh>​
 +  * Línea 12: Hemos añadido la clase ''​es.cursoangularjs.inyecciondependencias.json.JsonTransformerImplJackson''​ diciendo que ahora puede ser inyectada si solicitan una implementación del interfaz ''​JsonTransformer''​
 +  ​
 +¿Como sabe Spring que esa clase se debe inyectar si solicitan el interfaz ''​JsonTransformer''?​ Muy sencillo porque mira la clase y ve que implementa ese interfaz.
 +
 +Ahora debemos modificar el controlador para que le inyecten la clase definida en el fichero ''​applicationContext.xml''​.
 +
 +<sxh java;​title:​UsuaroiController.java;​highlight:​ [4,5]>
 +@Controller
 +public class UsuarioController {
 +    ​
 +    @Autowired
 +    private JsonTransformer jsonTransformer;​
 +    ​
 +    @RequestMapping(value = {"/​Usuario"​})
 +    public void prueba(HttpServletRequest httpRequest,​ HttpServletResponse httpServletResponse) throws IOException {
 +        Usuario usuario=new Usuario("​Alberto Tortosa","​alberto_tortosa@gmail.com",​91);​
 +        String jsonUsuario=jsonTransformer.toJson(usuario);​
 +        ​
 +        httpServletResponse.getWriter().println(jsonUsuario);​
 +    }
 +}
 +</​sxh>​
 +  * Línea 5: Esta línea le dice a Spring que debe buscar una implementación del interfaz que hay a continuación y asignarle una instancia a la propiedad.
 +  * Línea 6: Declaramos ahora la propiedad privada ''​jsonTransformer''​ pero no indicamos el objeto que lo implementa. Eso lo inyectará automáticamente Spring
 +
 +Es decir que ahora la configuración sobre de implementaciones debemos usar está centralizada en el fichero ''​applicationContext.xml''​ y el resto de la aplicación gracias a la anotación ''​@Autowired''​ permite que se le inyecte la implementación que está definida en el fichero. Es decir que inyectar significa simplemente asignar un objeto a una propiedad pero sin que la clase a la que se le inyecta el objeto sepa de que clase es.
 +
 +<note important>​
 +Una cosa importante a tener en cuenta es que spring solo va a crear un única instancia de objeto a inyectar en toda la aplicación por lo que hay que tener cuidado con mantener un estado en el objeto o controlar el acceso de varias threads a la vez.
 +</​note>​
 +===== Ejemplo =====
 +El ejemplo de esta unidad es exactamente lo que acabamos de contar pero es un nuevo proyecto llamado "​inyecciondependencias"​.
 +Lo único que debes recordar es que se han añadido también las librerías de Jackson y Spring.
 +
 +<​note>​
 +Este ejemplo se encuentra en  git en [[https://​github.com/​logongas/​cursoangularjs/​tree/​master/​inyecciondependencias]]
 +</​note>​
 +
  
unidades/10_servidor/04_inyecciondependencias.1409433503.txt.gz · Última modificación: 2014/08/30 23:18 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0