org.springframework.beans.factory.UnsatisfiedDependencyException org.springframework.beans.factory.NoUniqueBeanDefinitionException - PullRequest
0 голосов
/ 03 сентября 2018

Как устранить неоднозначности в АВТОМАТИЧЕСКОМ СОЕДИНЕНИИ бобов весной? У нас есть интерфейс Dessert, и у нас есть три различных десерта (Beans), которые реализуют интерфейс (Dessert).

Десерт дня - Печенье, поэтому мы записали его как любимое с @Primary.

Проблема в том, что десерты были сделаны просто, и если кто-то захочет повторить десерт, больше не будет печенья, поэтому мы создали "repeatDessert" для тех, кто хочет повторить десерт.

В дополнение к любимому десерту, есть еще два десерта, ТОРТ И МОРОЖЕНОЕ. Мы хотим, чтобы всем, кто повторяется, был подан десерт IceCream, которого у нас достаточно.

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

public interface Dessert {
    void eat();
}

ТОРТОВЫЙ ТОРТ:

@Component
public class Cake implements Dessert{

    private Dessert repeatDessert;

    public Dessert getRepeatDessert() {
        return repeatDessert;
    }

    @Autowired
    public void setRepeatDessert(Dessert repeatDessert) {
       this.repeatDessert = repeatDessert;
    }

    @Override
    public void eat() {
        System.out.println("Eating a Cake !!!!");
    }
}

БИО КУКИ:

@Component
@Primary
public class Cookie implements Dessert{

    private Dessert repeatDessert;

    public Dessert getRepeatDessert() {
        return repeatDessert;
    }

    @Autowired
    public void setRepeatDessert(Dessert repeatDessert) {
       this.repeatDessert = repeatDessert;
    }

    @Override
    public void eat() {
        System.out.println("Eating a Cookie !!!!");
    }
}

Бобовое мороженое:

@Component
public class IceCream implements Dessert{

    private Dessert repeatDessert;

    public Dessert getRepeatDessert() {
        return repeatDessert;
    }

    @Autowired
    public void setRepeatDessert(Dessert repeatDessert) {
       this.repeatDessert = repeatDessert;
    }

    @Override
    public void eat() {
        System.out.println("Eating a IceCream !!!!");
    }
}

Это будет файл конфигурации:

@Configuration
@ComponentScan
public class AutoBeanConfiguration {

}

Это будет основной класс:

public class Main {

    public static void main(String[] args) {
        BasicConfigurator.configure();
        Logger.getRootLogger().setLevel(Level.ERROR);
        AnnotationConfigApplicationContext ctxt = new AnnotationConfigApplicationContext(AutoBeanConfiguration.class);
        Cookies cookies = ctxt.getBean(Cookies.class);
        cookies.eat();
        Dessert dessert = cookies.getRepeatDessert();
        dessert.eat();
        ctxt.close();
    }

}

Программа выдает следующее exception:

Exception in thread "main" Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cookies': Unsatisfied dependency expressed through method 'setRepeatDessert' parameter 0;
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'Dessert' available: expected single matching bean but found 2: cake,iceCream

Как мы можем устранить неоднозначность и сказать весне, какой из десертов мы хотим создать, когда хотим повторить?

Вывод на консоль должен быть таким:

Eating a Cookies !!!!
Eating a IceCream !!!!

1 Ответ

0 голосов
/ 03 сентября 2018

Прежде всего, ваш код имеет ошибку компиляции. Пожалуйста, измените этот код

Cookies cookies = ctxt.getBean(Cookies.class);

до

Cookie cookie = ctxt.getBean(Cookie.class);

И затем в вашем классе компонентов все методы сеттера имеют то же имя, что и repeatDessert. Таким образом, это находит любые бины repeatDessert так же, как это имя. Так что это не может найти какой-либо компонент с этим. В вашем методе установки компонента класса;

@Autowired
public void setRepeatDessert(Dessert repeatDessert) {
   this.repeatDessert = repeatDessert;
}

Параметр метода repeatDessert не указан для каких компонентов. если вы измените весь класс бина, как это, с помощью Qualifier. Подробнее о квалификаторе ;

Для Cake.class;

@Autowired
@Qualifier("cake")
public void setRepeatDessert(Dessert repeatDessert) {
    this.repeatDessert = repeatDessert;
}

Для IceCream.class;

@Autowired
@Qualifier("iceCream")
public void setRepeatDessert(Dessert repeatDessert) {
    this.repeatDessert = repeatDessert;
}

для Cake.class;

@Autowired
@Qualifier("cake")
public void setRepeatDessert(Dessert repeatDessert) {
    this.repeatDessert = repeatDessert;
}

Теперь ваш весенний проект работает. Но ваш результат я думаю не могу дать. Поскольку у вас нет никакой информации о мороженом в вашей основной, только у вас есть Cookie, но вы хотите напечатать Eating a IceCream !!!!. Я не понял из вашего вывода. Можете ли вы предоставить, если это не может помочь вашей проблеме?

PS: Если вы хотите изменить repeatDessert вашего класса, вы можете изменить с помощью @Qualifier("yourBeanName");, и вы можете обеспечить повторяемую пустыню чего угодно.

...