Як весняне автопровідне ім'я за назвою, коли знайдено більше одного збіжжя?


106

Припустимо, у мене є такі інтерфейси:

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.


Думаю, я додам, що в одному (тестовому) середовищі я отримував "Не унікальний боб типу ...", і він добре працював у моєму середовищі розробки. Я впевнений, що це була якась річ класового шляху, але виявилося, якщо додати @Qualifier, це спрацювало чудово.
markthegrea

Відповіді:


113

Це задокументовано у розділі 3.9.3 посібника Spring 3.0:

Для резервного матчу ім'я біна вважається значенням класифікатора за замовчуванням.

Іншими словами, поведінка за замовчуванням така, ніби ви додали @Qualifier("country")до методу встановлення.


Коли ви говорите "ім'я квасолі", ви маєте на увазі ім'я поля, яке міститиме квасоля? (тобто в даному випадку country)
Позов

67

Можна використовувати анотацію @Qualifier

від сюди

Точне налаштування автопроводки на основі анотацій із кваліфікаторами

Оскільки автопроводка за типом може призвести до декількох кандидатів, часто необхідно мати більше контролю над процесом вибору. Один із способів цього досягти - анотація Spring @Qualifier Spring. Це дозволяє асоціювати значення класифікатора з конкретними аргументами, звужуючи набір відповідностей типів таким чином, що для кожного аргументу вибирається конкретна квасоля. У найпростішому випадку це може бути просте описове значення:

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

Це використовує Великобританію, щоб додати ідентифікатор до американського боба і використовувати його, якщо ви хочете США.


12

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

public class Main {
     private Country country;

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

У цьому випадку "#{country}рядок - це вираз Spring Expression Language (SpEL), який оцінюється на ім'я квасолі country.


чи можна це вводити на основі власності? що робити, якщо США чи Великобританія - це якийсь параметр, що надходить із URL-адреси, і я хочу ввести 2 різні речі на основі того, що парам?
Калпеш Соні

6

Ще одне рішення з вирішенням по імені:

@Resource(name="country")

Він використовує пакет javax.annotation , тому він не є специфічним для Spring, але Spring підтримує його.


1
але @Resourceне буде там поза коробкою з java 11 завдяки
Дірк Хофманн

5

у деяких випадках можна використовувати примітку @Primary.

@Primary
class USA implements Country {}

Таким чином, він буде обраний кандидатом автопроводу за замовчуванням, без необхідності автоматичного проводки-кандидата на іншому бобі.

для деатилів дивіться на Автомобільне з'єднання двох бобів, що реалізують один і той же інтерфейс - як встановити бін за замовчуванням для автопроводу?

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.