Как Spring autowire по имени, когда найдено более одного соответствия bean?

Предположим, что у меня есть такие интерфейсы, как:

interface Country {}
class USA implements Country {}
class UK implements Country ()

И этот фрагмент конфигурации xml:

<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>

Как я могу контролировать, какая из зависимостей автоподключена ниже? Я бы хотел, чтобы Великобритания.

class Main {
    private Country country;
    @Autowired
    public void setCountry(Country country) {
        this.country = country;
    }
}

Я использую Spring 3.0.3.RELEASE.

Ответ 1

Это описано в в разделе 3.9.3 руководства Spring 3.0:

Для ответного соответствия имя bean считается значением классификатора по умолчанию.

Другими словами, поведение по умолчанию, как если бы вы добавили @Qualifier("country") в метод setter.

Ответ 2

Вы можете использовать аннотацию @Qualifier

От здесь

Тонкая настройка автонастройки на основе аннотаций с квалификаторами

Так как автосогласование по типу может приводить к нескольким кандидатам, часто необходимо иметь больший контроль над процессом выбора. Один из способов добиться этого - аннотация Spring @Qualifier. Это позволяет связать значения квалификатора с конкретными аргументами, сужая набор совпадений типа, чтобы для каждого аргумента был выбран конкретный bean. В простейшем случае это может быть простое описательное значение:

class Main {
    private Country country;
    @Autowired
    @Qualifier("country")
    public void setCountry(Country country) {
        this.country = country;
    }
}

Это будет использовать Великобританию, добавив идентификатор в США bean и использовать это, если вы хотите США.

Ответ 3

Другим способом достижения такого же результата является использование аннотации @Value:

public class Main {
     private Country country;

     @Autowired
     public void setCountry(@Value("#{country}") Country country) {
          this.country = country;
     }
}

В этом случае строка "#{country} представляет собой выражение Spring выражение (SpEL), которое оценивается как bean с именем country.

Ответ 4

Еще одно решение с разрешением по имени:

@Resource(name="country")

Он использует пакет javax.annotation, поэтому не имеет значения Spring, но Spring поддерживает его.

Ответ 5

В некоторых случаях вы можете использовать аннотацию @Primary.

@Primary
class USA implements Country {}

Таким образом, он будет выбран в качестве автозапуска автозапуска по умолчанию, при этом нет необходимости использовать autowire-кандидат на другом bean.

для mo deatils посмотрите Autowiring два beans, реализующие один и тот же интерфейс - как установить по умолчанию bean для автоустройства?