Я пытаюсь автоматически связать свои bean-компоненты с помощью @qualifier, но даже после добавления классификатора я получаю исключение "required single bean" - PullRequest
0 голосов
/ 15 января 2020

BubbleSort. java Этот класс реализует интерфейс SortAlgorithm

package com.prakash.Spring.Example;

import org.springframework.stereotype.Component;

@Component
@Qualifier("bubbleSort")
public class BubbleSort implements SortAlgorithm {

    public void sort() {
        System.out.println("Sort from Bubble Sort");
    }
}

QuickSort. java Этот класс реализует пакет интерфейса SortAlgorithm com.praka sh .Spring.Example;

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Primary;

import org.springframework.stereotype.Component;

@Component
@Qualifier("quickSort")
public class QuickSort implements SortAlgorithm {

    @Override
    public void sort() {
        System.out.println("Sort from Quick Sort");
    }

}

SortAlgorithm. java

package com.prakash.Spring.Example;

public interface SortAlgorithm {
 void sort();
}

BinarySearch. java В этом классе Я хотел бы использовать bean-компонент quickSort в качестве своего компонента.

package com.prakash.Spring.Example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class BinarySearch {

    @Autowired
    @Qualifier("quickSort")
    private SortAlgorithm sortAlgorithm;

    public BinarySearch(SortAlgorithm sortAlgorithm) {
        super();
        this.sortAlgorithm = sortAlgorithm;
    }

    public int[] search(int[] numbers) {
        sortAlgorithm.sort();
        System.out.println("This is from BinarySearch");
        return numbers;
    }
}

ComplexBusinessService. java В этом классе я получаю bean-компонент с помощью метода getBean

package com.prakash.Spring.Example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class ComplexBussinessService {

    public static void main(String[] args) {

        ConfigurableApplicationContext applicationContext = SpringApplication.run(ComplexBussinessService.class, args);
        BinarySearch binarySearch = applicationContext.getBean(BinarySearch.class);
        int[] result = binarySearch.search(new int[] { 2, 4, 3 });
        for (int i : result) {
            System.out.print(i+" ");
        }
        applicationContext.close();

    }
}

Ответы [ 4 ]

1 голос
/ 15 января 2020

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

Вот порядок внедрения зависимости:

  1. Инъекция с помощью конструктора класса
  2. Инъекция полей (аннотирована @Autowired)
  3. Инъекция сеттеров (также аннотирована @Autowired)

Трюки здесь: Если класс, аннотированный @Component, также имеет только один конструктор не по умолчанию, тогда этот конструктор автоматически называется . Когда вы вызываете сначала конструктор, а затем поле, ваш @Qualifier даже не интерпретируется Spring, потому что он завершается с ошибкой во время вызова конструктора, поэтому возникает исключение.

Чтобы решить эту проблему, у вас есть два варианта:

  1. Либо удалите ваш конструктор из BinarySearch. Затем Spring вызовет конструктор по умолчанию new BinarySearch(), а затем выполнит внедрение в ваше поле sortAlgorithm, используя @Qualifier.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class BinarySearch {

    @Autowired
    @Qualifier("quickSort")
    private SortAlgorithm sortAlgorithm;

    public int[] search(int[] numbers) {
        sortAlgorithm.sort();
        System.out.println("This is from BinarySearch");
        return numbers;
    }
}
Или удалите аннотацию вашего поля и добавьте @Qualifier в свой параметр конструктора:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class BinarySearch {

    private SortAlgorithm sortAlgorithm;

    public BinarySearch(@Qualifier("quickSort") SortAlgorithm sortAlgorithm) {
        super();
        this.sortAlgorithm = sortAlgorithm;
    }

    public int[] search(int[] numbers) {
        sortAlgorithm.sort();
        System.out.println("This is from BinarySearch");
        return numbers;
    }
}

Надеюсь, это поможет!

0 голосов
/ 16 января 2020

В дополнение к отличному ответу от "RUARO Thibault", еще один способ устранить эту ошибку - это то, как Spring Boot упоминает, когда приложение не запускается.

Аннотирование одного из классов реализации с @Primary сделает этот бин в качестве основного кандидата, когда для автоматической проводки найдено несколько кандидатов.

@Component
@Qualifier("b")
@Primary
public class BubbleSortAlgorithm implements SortAlgorithm {}

В этом случае бин BinarySearch будет создан с кандидатом, помеченным @Primary. Затем происходит инъекция поля, когда он заменяется на bean-компонент с @Qualifier ("quickSort")

0 голосов
/ 15 января 2020
package com.prakash.Spring.Example;

import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Qualifier;
@Component
@Qualifier("bubbleSort")
public class BubbleSort implements SortAlgorithm {

public void sort() {
    System.out.println("Sort from Bubble Sort");
}
}

Я не вижу оператора импорта для аннотации Qualifier в классе BubbleSort. Не могли бы вы импортировать, а затем попробовать, если он работает

0 голосов
/ 15 января 2020

Вы также должны установить аннотацию @Qualifier для типа, который вы аннотировали @Component, например, так:

import org.springframework.beans.factory.annotation.Qualifier;

import org.springframework.context.annotation.Primary;

import org.springframework.stereotype.Component;

@Component
@Qualifier("quickSort")
public class QuickSort implements SortAlgorithm {

    @Override
    public void sort() {
        System.out.println("Sort from Quick Sort");
    }

}
...