Dependency injection без XML. @Autowired.

 
 
 
Сообщения:5
Hello, world!

Учу Spring по учебнику. Наткнулся на проблему - зависимости не внедряются. Обыскал уйму источников в инете, а там везде одно и то же пишут. Но у меня оно не работает. Работаю в Idea и Maven.
Есть, значит, Эминем
@Component 
public class Eminem {
    public void sing (){
        System.out.println("Эминем читает рэп.");
    }
}


Есть концерт
@Component ("concertoId")
public class Concerto {
    private Eminem eminem;

    @Autowired
    public Concerto(Eminem eminem) {
        this.eminem = eminem;
    }

    public void doConcerto(){
        eminem.sing();
    }
}


Есть конфиг
@Configuration
@ComponentScan("beans")
public class Config {

    @Bean
    public Concerto concertoId(){
        return new Concerto(eminemId());
     }

    @Bean
    public Eminem eminemId(){
        return new Eminem();
    }
}


Есть Main
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
        Concerto concerto = applicationContext.getBean("concertoId", Concerto.class);
        concerto.doConcerto();
    }
}


Этот код работает, но я хочу знать всё ли я правильно понял, а потому вопросы:
1. Правильно ли я понял, что определение зависимостей осуществляется передачей ссылок в файле конфигурации? Например return new Concerto(eminemId()); (строка 7 конфиг-класса). Об этом я спрашиваю, потому что во всех примерах в инете нет ничего такого. Там просто return new Concerto(); А иногда и вообще нет конфиг-класса. Я не понимаю как передаются зависимости, если нет конфиг-класса.
2. Что в книге, что в примерах из инета говорится следующее: чтобы внедрить зависимость через метод, а не конструктор, просто уберите Autowired перед конструктором и поставьте его перед методом. Но это не работает! Я даже копировал готовые примеры из инета. Они тоже не работают. Я уже почти отчаялся. Помогите, пожалуйста.

Дорогу осилит идущий
 
 
Сообщения:577
У вас просто spring или spring boot?
Если spring boot, то ему для совсем простеньких приложений конфиг-класс не нужен.
В конфиге у вас указано
@ComponentScan("beans")

Ваши классы бинов точно лежат в пакете beans или его подпакетах?
 
 
Сообщения:5
Я еще не знаю что именно из себя представляет Boot. До такого я ещё не дошёл. У меня два пакета: beans и configs. Main лежит ступенью выше.

Дорогу осилит идущий
 
 
Сообщения:10006
Способы конфигурации в спринге:
1. Явно объявленные бины в XML (можно с autowired, можно без)
2. Явно объявленные бины в Java (autowired только с хаками). Это как раз когда return new Concerto().
3. Неявное описание бинов с помощью Component Scan'a (autowired обязателен). Можно хоть с XML, хоть с Java. В таком случае спринг сканирует указанные пакеты, находит там классы помеченные @Component и сам создает их инстансы.

Из этих трех подходов 3ий сегодня самый популярный. Но он также и самый непрофессиональный - хорошим тоном в программировании является явная логика.

У тебя счас смесь 2ого и 3его вариантов. Неважно куда ты ставишь @Autowired если у тебя на самом деле отрабатывает 2ой подход. Кстати, если конструктор всего один, то @Autowired явно ставить не нужно.

Также, имей в виду что в методы (setter'ы) мы редко передаем бины. Такое нужно только если параметр какой-то необязательный. В обычных же ситуациях у бинов все параметры обязательны и значит нужно передавать их через конструктор.
Изменен:03 июн 2020 10:13
 
 
Сообщения:5
Всё начинает работать, если убрать из конфиг-класса
 @Bean
    public Eminem eminemId(){
        return new Eminem();
    }

Дорогу осилит идущий
 
Модераторы:wedens
Сейчас эту тему просматривают:Нет