Come fa la primavera a sapere quale tipo polimorfico usare.
Finché esiste una sola implementazione dell'interfaccia e tale implementazione è annotata con @Component
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 in application-config.xml (o file di configurazione di primavera equivalente).
Ho bisogno di @Qualifier o @Resource?
Una volta che hai più di un'implementazione, devi qualificarle ognuna e durante il cablaggio automatico, dovrai usare l' @Qualifier
annotazione per iniettare l'implementazione giusta, insieme @Autowired
all'annotazione. Se si utilizza @Resource (semantica J2EE), è necessario specificare il nome del bean utilizzando l' name
attributo di questa annotazione.
Perché autorichiamo l'interfaccia e non la classe implementata?
In primo luogo, è sempre una buona pratica programmare codice per le interfacce in generale. In secondo luogo, in caso di primavera, è possibile iniettare qualsiasi implementazione in fase di esecuzione. Un caso d'uso tipico è quello di iniettare un'implementazione simulata 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 configurazione del tuo bean dovrebbe apparire così:
<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />
In alternativa, se hai abilitato la scansione dei componenti sul pacchetto in cui sono presenti, allora dovresti qualificare ciascuna classe @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();
}
Poi worker
in MyRunner
verrà iniettato con un'istanza di tipo B
.