Не происходит внедрение зависимостей через Spring

Рейтинг: 0Ответов: 1Опубликовано: 13.06.2023

Всем привет! Изучаю java, в качестве практики пишу pet проект. Для связи с базой данных в проекте использую такой репозиторий:

@Repository
public interface MeetingRepository extends CrudRepository<Meeting, Long> {
    boolean existsByPassphrase(String passphrase);
}

Однако, при использовании его в классе:

@Component
public class newMeeting implements ActionInterface {

    @Autowired
    MeetingRepository meetingRepository;
    @Autowired
    Meeting meeting;

    @Override
    public Update isPassphraseOk(Update update) {
        String passphrase = update.getMessage();
        String chatId = update.getChatID().toString();

        //вызов meetingRepository
        if (meetingRepository.existsByPassphrase(passphrase)) {
            String text = "Это название уже занято, попробуйте ввести другое название";
            update.setMessage(text);
            return update;
        } else {
            meeting.setPassphrase(passphrase);
            String text = "Это название уже занято, попробуйте ввести другое название";
            update.setMessage(text);
            return update;
        }
    }
} 

получаю

Exception in thread "main" java.lang.NullPointerException: 
Cannot invoke "org.example.MeetingRepository.existsByPassphrase(String)" 
because "this.meetingRepository" is null

Подскажите, почему не происходит внедрение зависимостей, хотя репозиторий помечен @Repository, поле помечено как @Autowired и Intrllij определяет правильно их использование?

UPD github проекта https://github.com/gleb-esin/meetingRepository_is_not_working

Ответы

▲ 2Принят

Проблема была в совершенно другом месте:

 private final Map<String, ActionInterface> actions = Map.of(
            "/new", new newMeeting());

newMeeting это бин, соответственно при создании этого класса через new, все внедряемые зависимости будут null. В том числе и зависимость на репозиторий. Как это решить:

  1. Расширить интерфейс ActionInterface методом, который возвращает стринговый ключ для соответствующего экшина

  2. Реализовать этот метод в пока единственной реализации этого интерфейса

  3. Заинжектить в бин TelegramBot все бины с типом ActionInterface - @Autowired private List<ActionInterface> actionBeans;

  4. Создать метод, который в зависимости от значения ключа выбирает нужный бин

    private ActionInterface resolveAction(String key) {

         for (var a : actionBeans) {
             if (a.getActionKey().equals(key)) {
                 return a;
             }
         }
         return null;
     }
    
  5. заменить все вызовы actions.get(key) на resolveAction(key)