Skip to content

3. Inversão de Controlo (IoC)

Vamos agora concentrar-nos no conceito de Inversão de Controlo (IoC) utilizado pelo Spring para configurar aplicações. Para ilustrar este conceito, voltemos à arquitetura da nossa aplicação de teste anterior:

Para aceder aos dados do SGBD, a classe de teste deve utilizar os serviços de um objeto que implemente a interface [IArticlesDao], por exemplo, um objeto do tipo [ArticlesDaoPlainODBC]. Analisámos duas soluções possíveis para instanciar tal objeto:

  • Na primeira solução, a própria classe de teste solicitou a instanciação de um objeto do tipo [ArticlesDaoPlainODBC]:
    <TestFixture()> _
    Public Class NunitTestArticlesDaoPlainOdbc

        ' the test object
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
            ' create an instance of the object to be tested
            articlesDao = New ArticlesDaoPlainODBC("odbc-firebird-articles", "SYSDBA", "masterkey")
        End Sub
...
    End Class

Existe uma dependência codificada no nome da classe no código. Se a classe que implementa a interface [IArticlesDao] fosse alterada, o código no método [init] teria de ser modificado. Existem as seguintes relações entre os objetos:

A classe [NunitTestArticlesDaoPlainOdbc] toma a iniciativa de criar o objeto [ArticlesDaoPlainODBC] de que necessita. Voltando ao termo «inversão de controlo», podemos dizer que é ela que tem o «controlo» sobre a criação do objeto de que necessita.

  • A segunda solução adota uma abordagem diferente. A classe de teste passou a ser a seguinte:
    <TestFixture()> _
    Public Class NunitSpringTestArticlesDaoPlainOdbc

        ' the test object
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
      ' retrieve an instance of the Spring object manufacturer
            Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
      ' request instantiation of the articles dao object
            articlesDao = CType(factory.GetObject("articlesdao"), IArticlesDao)
        End Sub
    ...
    End Class

Este mecanismo pode ser resumido da seguinte forma:

Aqui, a classe de teste não toma a iniciativa de solicitar a criação de um objeto [ArticlesDaoPlainODBC]. Simplesmente pede ao Spring uma referência a esse objeto. Se o objeto existir, o Spring devolve uma referência ao mesmo. Se não existir, o Spring cria-o. A classe de teste perdeu o controlo sobre a criação do objeto [ArticlesDaoPlainODBC]. Simplesmente solicita uma referência a este objeto. Este pedido obrigará o Spring a criar o objeto neste caso. No entanto, noutro contexto, é possível imaginar que o objeto solicitado já tenha sido criado a pedido da aplicação. O Spring, nesse caso, não recria o objeto, mas devolve uma referência ao objeto existente (singleton). O conceito de Inversão de Controlo (IoC) significa aqui:

  • que a aplicação nunca toma a iniciativa de criar os singletons de que necessita. Simplesmente solicita referências aos mesmos.
  • É o Spring que decide criar um singleton na primeira solicitação de uma referência a ele