Перейти к основному содержимому

Неудовлетворенная зависимость в Spring

· 3 мин. чтения

Задача: Сумма двух

Дано массив целых чисел и целая сумма. Нужно найти индексы двух чисел, сумма которых равна заданной ...

ANDROMEDA

1. Обзор

В этом кратком руководстве мы объясним Spring UnsatisfiedDependencyException , что вызывает его и как его избежать.

2. Причина исключения UnsatisfiedDependencyException

UnsatisfiedDependencyException возникает, когда, как следует из названия, зависимость какого-либо компонента или свойства не удовлетворена.

Это может произойти, когда приложение Spring пытается связать компонент и не может разрешить одну из обязательных зависимостей.

3. Пример приложения

Предположим, у нас есть класс сервиса PurchaseDeptService , который зависит от InventoryRepository :

@Service
public class PurchaseDeptService {
public PurchaseDeptService(InventoryRepository repository) {
this.repository = repository;
}
}
public interface InventoryRepository {
}
@Repository
public class ShoeRepository implements InventoryRepository {
}
@SpringBootApplication
public class SpringDependenciesExampleApplication {

public static void main(String[] args) {
SpringApplication.run(SpringDependenciesExampleApplication.class, args);
}
}

Пока будем считать, что все эти классы находятся в одном пакете с именем com.foreach.dependency.exception.app .

Когда мы запускаем это приложение Spring Boot, все работает нормально.

Давайте посмотрим, с какими проблемами мы можем столкнуться, если пропустим шаг настройки.

4. Отсутствует аннотация компонента

Теперь давайте удалим аннотацию @Repository из нашего класса ShoeRepository :

public class ShoeRepository implements InventoryRepository {
}

Когда мы снова запустим наше приложение, мы увидим следующее сообщение об ошибке: UnsatisfiedDependencyException: Ошибка создания bean-компонента с именем «purchaseDeptService»: неудовлетворенная зависимость, выраженная через параметр конструктора 0

Spring не был проинструктирован о подключении bean-компонента ShoeRepository и добавлении его в контекст приложения, поэтому он не мог внедрить его и выдал исключение.

Добавление аннотации @Repository обратно в ShoeRepository решает проблему.

5. Пакет не отсканирован

Давайте теперь поместим наш ShoeRepository (вместе с InventoryRepository ) в отдельный пакет с именем com.foreach.dependency.exception.repository .

Еще раз, когда мы запускаем наше приложение, оно генерирует исключение UnsatisfiedDependencyException .

Чтобы решить эту проблему, мы можем настроить сканирование пакета в родительском пакете и убедиться, что включены все соответствующие классы:

@SpringBootApplication
@ComponentScan(basePackages = {"com.foreach.dependency.exception"})
public class SpringDependenciesExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDependenciesExampleApplication.class, args);
}
}

6. Разрешение неуникальных зависимостей

Предположим, мы добавляем еще одну реализацию InventoryRepositoryDressRepository :

@Repository
public class DressRepository implements InventoryRepository {
}

Теперь, когда мы запускаем наше приложение, оно снова выдает исключение UnsatisfiedDependencyException .

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

Чтобы решить эту проблему, мы можем добавить @Qualifier , чтобы различать репозитории:

@Qualifier("dresses")
@Repository
public class DressRepository implements InventoryRepository {
}
@Qualifier("shoes")
@Repository
public class ShoeRepository implements InventoryRepository {
}

Кроме того, нам нужно будет добавить квалификатор в зависимость конструктора PurchaseDeptService :

public PurchaseDeptService(@Qualifier("dresses") InventoryRepository repository) {
this.repository = repository;
}

Это сделает DressRepository единственным жизнеспособным вариантом, и Spring внедрит его в PurchaseDeptService .

7. Заключение

В этой статье мы увидели несколько наиболее частых случаев возникновения UnsatisfiedDependencyException , а затем узнали, как решать эти проблемы.

У нас также есть более общий учебник по Spring BeanCreationException .

Представленный здесь код можно найти на GitHub .