Skip to content

3. Inversión de control IoC

Ahora analicemos el concepto de inversión de control (IoC, Inversion of Control) que utiliza Spring para configurar las aplicaciones. Para ilustrar este concepto, volvamos a la arquitectura de nuestra aplicación de prueba anterior:

Para acceder a los datos de SGBD, la clase de prueba debe utilizar los servicios de un objeto que implemente la interfaz [IArticlesDao], por ejemplo, un objeto de tipo [ArticlesDaoPlainODBC]. Hemos analizado dos soluciones posibles para instanciar dicho objeto:

  • en la primera solución, la clase de prueba solicitaba por sí misma la instanciación de un objeto de tipo [ArticlesDaoPlainODBC]:
    <TestFixture()> _
    Public Class NunitTestArticlesDaoPlainOdbc

         ' el objeto a probar
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
             ' se crea una instancia del objeto a probar
            articlesDao = New ArticlesDaoPlainODBC("odbc-firebird-articles", "SYSDBA", "masterkey")
        End Sub
...
    End Class

Existe una dependencia fija en el código con respecto al nombre de la clase. Si la clase de implementación de la interfaz [IArticlesDao] llegara a cambiar, habría que modificar el código del método [init]. Existen las siguientes relaciones entre los objetos:

La clase [NunitTestArticlesDaoPlainOdbc] se encarga por sí misma de crear el objeto [ArticlesDaoPlainODBC] que necesita. Volviendo al término «inversión de control», diremos que es ella quien tiene el «control» para crear el objeto que necesita.

  • La segunda solución funciona de manera diferente. La clase de prueba quedó así:
    <TestFixture()> _
    Public Class NunitSpringTestArticlesDaoPlainOdbc

         ' el objeto a probar
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
       ' se obtiene una instancia del generador de objetos de Spring
            Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
       ' se solicita la instanciación del objeto DAO de artículos
            articlesDao = CType(factory.GetObject("articlesdao"), IArticlesDao)
        End Sub
    ...
    End Class

Este mecanismo podría esquematizarse de la siguiente manera:

Aquí, la clase de prueba no toma la iniciativa de solicitar la creación de un objeto [ArticlesDaoPlainODBC]. Simplemente le pide a Spring una referencia a dicho objeto. Si el objeto existe, Spring devuelve una referencia al mismo. Si no existe, lo crea. La clase de prueba ha perdido el control sobre la creación del objeto [ArticlesDaoPlainODBC]. Simplemente solicita una referencia a dicho objeto. En este caso, dicha solicitud obligará a Spring a crear el objeto. Sin embargo, en otro contexto, se podría imaginar que el objeto solicitado ya haya sido creado a petición de la aplicación. En ese caso, Spring no vuelve a crear el objeto, sino que devuelve una referencia al objeto ya existente (singleton). El concepto de Inversión de control (IoC) significa aquí:

  • que la aplicación nunca toma la iniciativa de crear los singletons que necesita. Simplemente solicita referencias a ellos.
  • Es Spring quien toma la decisión de crear un singleton al recibir la primera solicitud de referencia sobre él