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

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

1. обзор

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

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.example.dependency.exception.app.

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

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

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

public class ShoeRepository implements InventoryRepository {
}

Когда мы снова запустим наше приложение, мы увидим следующее сообщение об ошибке:UnsatisfiedDependencyException: Error creating bean with name ‘purchaseDeptService': Unsatisfied dependency expressed through constructor parameter 0

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

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

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

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

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

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

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

Допустим, мы добавляем еще одну реализациюInventoryRepository -DressRepository:

@Repository
public class DressRepository implements InventoryRepository {
}

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

Однако на этот раз ситуация другая. Как оказалось,dependency cannot be resolved when there’s more than one bean that satisfies it.

Чтобы решить эту проблему, мы можем добавить@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.

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