Как Spring узнает, какой полиморфный тип использовать.
Пока существует только одна реализация интерфейса и эта реализация аннотирована с @Component
включенным сканированием компонентов Spring, среда Spring может найти пару (интерфейс, реализация). Если сканирование компонентов не включено, вам необходимо явно определить компонент в файле application-config.xml (или эквивалентном файле конфигурации Spring).
Мне нужен @Qualifier или @Resource?
Если у вас есть более одной реализации, вам необходимо квалифицировать каждую из них, и во время автоматического подключения вам нужно будет использовать @Qualifier
аннотацию для внедрения правильной реализации вместе с @Autowired
аннотацией. Если вы используете @Resource (семантика J2EE), вы должны указать имя bean-компонента, используя name
атрибут этой аннотации.
Почему мы автоматически подключаем интерфейс, а не реализованный класс?
Во-первых, всегда полезно кодировать интерфейсы в целом. Во-вторых, в случае Spring вы можете внедрить любую реализацию во время выполнения. Типичный вариант использования - внедрить фиктивную реализацию на этапе тестирования.
interface IA
{
public void someFunction();
}
class B implements IA
{
public void someFunction()
{
}
public void someBfunc()
{
}
}
class C implements IA
{
public void someFunction()
{
}
public void someCfunc()
{
}
}
class MyRunner
{
@Autowire
@Qualifier("b")
IA worker;
....
worker.someFunction();
}
Конфигурация вашего bean-компонента должна выглядеть так:
<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />
В качестве альтернативы, если вы включили сканирование компонентов в пакете, где они присутствуют, вы должны квалифицировать каждый класс @Component
следующим образом:
interface IA
{
public void someFunction();
}
@Component(value="b")
class B implements IA
{
public void someFunction()
{
}
public void someBfunc()
{
}
}
@Component(value="c")
class C implements IA
{
public void someFunction()
{
}
public void someCfunc()
{
}
}
@Component
class MyRunner
{
@Autowire
@Qualifier("b")
IA worker;
....
worker.someFunction();
}
Затем worker
в MyRunner
будет введен с экземпляром типа B
.