пример
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();
}
Может кто-то объяснить это мне.
- Как Spring узнает, какой полиморфный тип использовать.
- Мне нужно
@Qualifier
или@Resource
? - Почему мы автоматически подключаем интерфейс, а не реализованный класс?
java
spring
dependency-injection
переполнение стека
источник
источник
Ответы:
Пока существует только одна реализация интерфейса и эта реализация аннотирована с
@Component
включенным сканированием компонентов Spring, среда Spring может найти пару (интерфейс, реализация). Если сканирование компонентов не включено, вам необходимо явно определить компонент в файле application-config.xml (или эквивалентном файле конфигурации Spring).Если у вас есть более одной реализации, вам необходимо квалифицировать каждую из них, и во время автоматического подключения вам нужно будет использовать
@Qualifier
аннотацию для внедрения правильной реализации вместе с@Autowired
аннотацией. Если вы используете @Resource (семантика J2EE), вы должны указать имя bean-компонента, используяname
атрибут этой аннотации.Во-первых, всегда полезно кодировать интерфейсы в целом. Во-вторых, в случае Spring вы можете внедрить любую реализацию во время выполнения. Типичный вариант использования - внедрить фиктивную реализацию на этапе тестирования.
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(); }
Конфигурация вашего 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() { //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(); }
Затем
worker
вMyRunner
будет введен с экземпляром типаB
.источник
@Autowired @Qualifier("a1") a;
Действителен?@Autowired @Qualifier("a1") A a;
Также это может вызвать некоторые предупреждения в журналах, такие как Cglib2AopProxy Unable to proxy method . И многие другие причины для этого описаны здесь. Почему всегда есть единые интерфейсы реализации на уровнях обслуживания и dao?
источник