Unsatisfied Dependency in Spring – Spring里的不满足的依赖性

最后修改: 2018年 9月 18日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll explain Spring’s UnsatisfiedDependencyException, what causes it and how to avoid it.

在这个快速教程中,我们将解释Spring的UnsatisfiedDependencyException,它的原因以及如何避免它。

2. Cause of UnsatisfiedDependencyException

2.造成UnsatisfiedDependencyException的原因

UnsatisfiedDependencyException gets thrown when, as the name suggests, some bean or property dependency isn’t satisfied.

UnsatisfiedDependencyException当顾名思义,某些bean或属性的依赖性没有得到满足时,会被抛出。

This may happen when a Spring application tries to wire a bean and can’t resolve one of the mandatory dependencies.

当Spring应用程序试图连接一个Bean,但无法解决其中一个强制性的依赖关系时,就会发生这种情况。

3. Example Application

3.应用实例

Suppose we have a service class PurchaseDeptService, which depends on InventoryRepository:

假设我们有一个服务类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);
    }
}

For now, we’ll assume that all these classes are located in the same package named com.baeldung.dependency.exception.app.

现在,我们假设所有这些类都位于同一个名为com.baeldung.dependency.exception.app的包中。

When we run this Spring Boot application, everything works fine.

当我们运行这个Spring Boot应用程序时,一切工作正常。

Let’s see what kind of issues we can run into if we skip a configuration step.

让我们看看如果我们跳过一个配置步骤,会遇到什么样的问题。

4. Component Annotation Missing

4.组件注释缺失

Now let’s remove the @Repository annotation from our ShoeRepository class:

现在让我们从我们的@Repository类中删除ShoeRepository注解。

public class ShoeRepository implements InventoryRepository {
}

When we start our application again, we’ll see the following error message: UnsatisfiedDependencyException: Error creating bean with name ‘purchaseDeptService’: Unsatisfied dependency expressed through constructor parameter 0

当我们再次启动我们的应用程序时,我们会看到以下错误信息。UnsatisfiedDependencyException。创建名称为’purchaseDeptService’的bean时出错。通过构造器参数0表达的依赖性不满足

Spring wasn’t instructed to wire a ShoeRepository bean and add it to the application context, so it couldn’t inject it and threw the exception.

Spring没有被指示去连接一个ShoeRepository Bean并将其添加到应用上下文中,所以它无法注入它,并抛出了这个异常。

Adding the @Repository annotation back onto the ShoeRepository solves the issue.

@Repository注解重新添加到ShoeRepository上就解决了这个问题。

5. Package Not Scanned

5.包裹未被扫描

Let’s now put our ShoeRepository (along with InventoryRepository) into a separate package named com.baeldung.dependency.exception.repository.

现在让我们把我们的ShoeRepository(连同InventoryRepository)放入一个单独的包,名为com.baeldung.dependency.exception.repository

Once again, when we run our app, it throws the UnsatisfiedDependencyException.

再一次,当我们运行我们的应用程序时,它抛出了UnsatisfiedDependencyException

To solve this, we can configure the package scan on the parent package and make sure that all relevant classes are included:

为了解决这个问题,我们可以在父包上配置包扫描,并确保所有相关的类都包括在内。

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

6. Non-unique Dependency Resolution

6.非唯一性的依赖关系解决

Suppose we add another InventoryRepository implementation — DressRepository:

假设我们添加另一个InventoryRepository实现 – DressRepository

@Repository
public class DressRepository implements InventoryRepository {
}

Now when we run our app, it will once again throw the UnsatisfiedDependencyException.

现在当我们运行我们的应用程序时,它将再次抛出UnsatisfiedDependencyException

However, this time the situation is different. As it happens, the dependency cannot be resolved when there’s more than one bean that satisfies it.

然而,这一次的情况有所不同。正如它所发生的,当有一个以上的bean满足它时,依赖性不能被解决。

To solve this, we may want to add @Qualifier to distinguish between the repositories:

为了解决这个问题,我们可能要添加@Qualifier来区分存储库。

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

Also, we’ll have to add a qualifier to PurchaseDeptService constructor dependency:

另外,我们还得给PurchaseDeptService构造函数依赖性添加一个限定符。

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

This will make DressRepository the only viable option, and Spring will inject it into PurchaseDeptService.

这将使DressRepository成为唯一可行的选择,Spring将把它注入PurchaseDeptService

7. Conclusion

7.结语

In this article, we saw several most common cases of encountering UnsatisfiedDependencyException, and then we learned how to solve these problems.

在这篇文章中,我们看到了遇到UnsatisfiedDependencyException的几种最常见的情况,然后我们学习了如何解决这些问题。

We also have a more general tutorial on Spring BeanCreationException.

我们还有一个关于Spring BeanCreationException的更一般性教程。

The code presented here can be found over on GitHub.

这里介绍的代码可以在GitHub上找到over