Spring: Perché realizziamo l’interfaccia e non la class implementata?

Esempio

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(); } 

Qualcuno può spiegarmelo.

  • Come fa la spring a sapere quale tipo di polimorfismo usare.
  • Ho bisogno di @Qualifier o @Resource ?
  • Perché realizziamo l’interfaccia e non la class implementata?

Come fa la spring a sapere quale tipo di polimorfismo usare.

Finché c’è solo una singola implementazione dell’interfaccia e @Component è annotata con @Component con la scansione dei componenti di Spring abilitata, il framework Spring può scoprire la coppia (interfaccia, implementazione). Se la scansione dei componenti non è abilitata, è necessario definire esplicitamente il bean nel file application-config.xml (o in un file di configurazione Spring equivalente).

Ho bisogno di @Qualifier o @Resource?

Dopo aver implementato più di una implementazione, è necessario qualificarne ciascuna e durante l’auto-wiring, sarà necessario utilizzare l’annotazione @Qualifier per iniettare l’implementazione corretta insieme all’annotazione @Autowired . Se si utilizza @Resource (semantica J2EE), è necessario specificare il nome del bean utilizzando l’attributo name di questa annotazione.

Perché realizziamo l’interfaccia e non la class implementata?

In primo luogo, è sempre buona norma codificare le interfacce in generale. In secondo luogo, in caso di spring, è ansible iniettare qualsiasi implementazione in fase di esecuzione. Un tipico caso d’uso è quello di iniettare un’implementazione fittizia durante la fase di 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(); } 

La tua configurazione del bean dovrebbe apparire così:

    

In alternativa, se hai abilitato la scansione dei componenti sul pacchetto in cui sono presenti, dovresti qualificare ogni class con @Component come segue:

 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(); } 

Quindi il worker in MyRunner verrà iniettato con un’istanza di tipo B

Inoltre può causare alcuni warnigs nei log come un metodo Cglib2AopProxy Unable to proxy . E qui vengono descritti molti altri motivi. Perché sempre le interfacce di implementazione singole nei livelli di servizio e dao?