Skip to content

3. Inversión de control IoC

Centrémonos ahora en 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 estudiado dos posibles soluciones para instanciar dicho objeto:

  • en la primera solución, la clase de prueba solicitaba ella 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 rígida 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] toma por sí misma la iniciativa de crear el objeto [ArticlesDaoPlainODBC] que necesita. Volviendo al término «inversión de control», diremos que es ella la que tiene el «control» para crear el objeto que necesita.

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

         ' el objeto a probar
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
       ' se recupera una instancia del generador de objetos Spring
            Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
       ' se solicita la instanciación del objeto artículos dao
            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]. Se limita a solicitar a Spring una referencia a dicho objeto. Si el objeto existe, Spring devuelve una referencia. 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. Esta solicitud obligará aquí a Spring a crear el objeto. Pero cabría imaginar, en otro contexto, que el objeto solicitado ya se haya 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 cuando se solicita por primera vez una referencia al mismo