180 votes

Spring: Pourquoi connectons-nous automatiquement l'interface et non la classe implémentée?

Exemple

 interface IA
{
  public void someFunction();
}

@Resource(name="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}

@Resource(name="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{

  @Autowire
  @Qualifier("b") 
  IA worker;

  worker.someFunction();
}
 

Quelqu'un peut m'expliquer cela.

  • Comment spring sait-il quel type polymorphe utiliser?
  • Ai-je besoin de @Qualifier ou @Resource ?
  • Pourquoi connectons-nous automatiquement l'interface et non la classe implémentée?

276voto

Vikdor Points 15049

Comment ne ressort savoir quel type polymorphe à utiliser.

Tant qu'il y est un seul de la mise en œuvre de l'interface et que la mise en œuvre est annotée avec l' @Component avec le Printemps, la composante de l'analyse activé, framework Spring pouvez trouver le (interface, la mise en œuvre) paire. Si le composant d'analyse n'est pas activée, vous devez définir le haricot explicitement dans votre application-config.xml (ou l'équivalent de printemps du fichier de configuration).

Ai-je besoin d' @Qualifier ou @Resource?

Une fois que vous avez plus d'une application, alors vous devez qualifier chacun d'eux et pendant l'auto-câblage, vous devez utiliser l' @Qualifier d'annotation pour injecter la bonne mise en œuvre, avec @Autowired d'annotation. Si vous utilisez @Ressource J2EE (sémantique), vous devez spécifier le haricot nom à l'aide de l' name attribut de cette annotation.

Pourquoi ne nous autowire l'interface et non pas la mise en œuvre de la classe?

Tout d'abord, il est toujours une bonne pratique de code pour les interfaces en général. Deuxièmement, en cas de printemps, vous pouvez injecter toute mise en œuvre lors de l'exécution. Un cas d'utilisation typique est d'injecter de se moquer de la mise en œuvre au cours de la phase de test.

interface IA
{
  public void someFunction();
}


class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Votre bean configuration devrait ressembler à ceci:

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />

Alternativement, si vous avez activé la composante d'analyse sur le paquet, où ceux-ci sont présents, alors vous devriez qualifier chaque classe avec @Component comme suit:

interface IA
{
  public void someFunction();
}

@Component(value="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


@Component(value="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

@Component    
class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Ensuite, worker en MyRunner sera injecté avec une instance de type B.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X