Abner Ballardo

Una de las características más importantes de Spring Framework es la inyección de dependencias. Aplicando este patrón podemos lograr que las clases dependan de interfaces y no de alguna implementación específica, los beneficios de esta forma de trabajo son innumerables y pueden encontrar varios artículos que los describen a profundidad en internet y en la documentación de Spring.

Pero que sucede si nos encontramos con el siguiente problema:

Estamos usando Spring MVC en una aplicación web pero nos vemos obligados a implementar un Servlet. Dentro de este Servlet tenemos que invocar a un Service que ya esta siendo administrado por el contexto de Spring.

El consejo del bug killer puede llevarnos por dos caminos en este escenario:

No buscar en internet a profundidad, ni preguntar y usar la solución más rápida que se te venga a la mente. Seguir el buen diseño y obtener una referencia al Service administrado por Spring. En el primer caso tendríamos un Servlet implementado de la siguiente manera:

public class DummyServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;

 public DummyServlet() {
   super();
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
   DummyService service = new DummyServiceImpl();
   resp.getWriter().print(bean.getMessage());
 }
}

¡Esta instanciando la implementación del Service directamente!,… esto puede traer serios problemas si se tiene que cambiar el DummyServiceImpl por otro en un futuro próximo o lejano. Lo más probable es que no se actualice el Servlet y se presente un comportamiento no esperado del sistema.

En el segundo caso, usaríamos las mismas clases de Spring para obtener una referencia al Service:

public class DummyServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;

 public DummyServlet() {
   super();
 }

 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                      throws ServletException, IOException {
   WebApplicationContext applicationContext = ContextLoader.getCurrentWebApplicationContext();
   DummyService service = (DummyService) applicationContext.getBean("DummyService");
   resp.getWriter().print(bean.getMessage());
 }
}

Manteniendo de esa manera el diseño y el patrón de inyección de dependiencias.

Happy Hacking!

UPDATE: Para simplificar el ejemplo de este articulo solo se instancia el Service en el Servlet pero debemos tener en cuenta que el Service puede depender de clases DAO o puede necesitar AOP. Esto agravaría más los problemas de instanciar una clase que ya esta siendo manejada por el contenedor IoC.