Skip to content

3. Inversion de contrôle IoC

Attardons-nous maintenant sur la notion d'inversion de contrôle (IoC, Inversion of Control) utilisée par Spring pour configurer les applications. Pour illustrer ce concept, revenons à l'architecture de notre application de test précédente :

Pour accéder aux données du SGBD, la classe de test doit utiliser les services d'un objet implémentant l'interface [IArticlesDao], par exemple un objet de type [ArticlesDaoPlainODBC]. Nous avons étudié deux solutions possibles pour instancier un tel objet :

  • dans la première solution, la classe de test demandait elle-même l'instanciation d'un objet de type [ArticlesDaoPlainODBC] :
    <TestFixture()> _
    Public Class NunitTestArticlesDaoPlainOdbc

        ' l'objet à tester
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
            ' on crée une instance de l'objet à tester
            articlesDao = New ArticlesDaoPlainODBC("odbc-firebird-articles", "SYSDBA", "masterkey")
        End Sub
...
    End Class

On a une dépendance en dur dans le code sur le nom de classe. Si la classe d'implémentation de l'interface [IArticlesDao] venait à changer, le code de la méthode [init] devrait être modifié. On a les relations suivantes entre les objets :

La classe [NunitTestArticlesDaoPlainOdbc] prend elle-même l'initiative de la création de l'objet [ArticlesDaoPlainODBC] dont elle a besoin. Pour en revenir au terme "inversion de contrôle", on dira que c'est elle qui a le "contrôle" pour créer l'objet dont elle a besoin.

  • la seconde solution procède différemment. La classs de test est devenue la suivante :
    <TestFixture()> _
    Public Class NunitSpringTestArticlesDaoPlainOdbc

        ' l'objet à tester
        Private articlesDao As IArticlesDao

        <SetUp()> _
        Public Sub init()
      ' on récupère une instance du fabricant d'objets Spring
            Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
      ' on demande l'instanciation de l'objet articles dao
            articlesDao = CType(factory.GetObject("articlesdao"), IArticlesDao)
        End Sub
    ...
    End Class

Ce mécanisme pourrait être schématisé comme suit :

Ici, la classe de test ne prend pas l'initiative de demander la création d'un objet [ArticlesDaoPlainODBC]. Elle se contente de demander à Spring, une référence sur un tel objet. Si l'objet existe, Spring en rend alors une référence. S'il n'existe pas, il le crée. La classe de test a perdu le contrôle de la création de l'objet [ArticlesDaoPlainODBC]. Elle demande simplement une référence sur cet objet. Cette demande va ici forcer Spring à créer l'objet. Mais on pourrait imaginer, dans un autre contexte, que l'objet demandé a déjà été créé à la demande de l'application. Spring ne recrée alors pas l'objet mais rend une référence sur l'objet déjà existant (singleton). La notion d'Inversion de contrôle (IoC) signifie ici :

  • que l'application ne prend jamais l'initiative de créer les singletons dont elle a besoin. Elle en demande simplement des références.
  • c'est Spring qui prend la décision de créer un singleton lors de la première demande de référence sur celui-ci