您的位置:

CouldNotAutowireField——常见spring异常的解决方式

一、原因概述

在开发过程中,可能会遇到CouldNotAutowireField这个异常。究其原因,通常是由于spring无法找到 Bean 来注入。常见的原因包括无法扫描到 Bean、多个 Bean 可以作为注入,但是没有指定优先级等等。

二、无法扫描到 Bean

导致spring无法注入 Bean 的原因有很多,其中一种比较常见的情况是没有将 Bean 注册到 spring 容器中。为了说明这个情况,我们创建一个简单的类 Student:

public class Student {
    private String name;
    private int age;
    // setters and getters
}

如果我们想要在另一个类中注入 Student,那么我们就需要在配置类中注册这个 Bean:

@Configuration
public class AppConfig {
    @Bean
    public Student student() {
        return new Student();
    }
}

对于该类,我们可以将 Bean 的创建过程委托给容器。注意在类上加 @Configuration 注解,表示这是一个配置类。当然还可以使用 @ComponentScan 注解进行自动扫描,自动注册 Bean。

@Configuration
@ComponentScan(basePackages = {"com.example"})
public class AppConfig {
 
}

以上两种方法都可以让 spring 进行扫描,将 Bean 注册到容器中。

三、多个 Bean 可以作为注入,但没有指定优先级

在很多情况下,我们可能会遇到同一个类型的多个实现,这时候我们需要指定注入哪一个 Bean。比如在以下的代码中,Cat 和 Dog 类的实现我们都需要注入,但是spring无法确定注入其中的哪一个。

@Service
public class UserService {
    @Autowired
    private Animal animal;
}
 
@Component
public class Cat implements Animal {
}
 
@Component
public class Dog implements Animal {
}

为了解决该问题,我们需要显式地告诉spring应该注入哪一个 Bean。有以下两种方式:

1、使用 @Qualifier 注解指定

@Service
public class UserService {
    @Autowired
    @Qualifier("cat")
    private Animal animal;
}
 
@Component("cat")
public class Cat implements Animal {
}
 
@Component("dog")
public class Dog implements Animal {
}

2、使用 @Primary 注解指定

@Service
public class UserService {
    @Autowired
    private Animal animal;
}
 
@Component
@Primary
public class Cat implements Animal {
}
 
@Component
public class Dog implements Animal {
}

四、注入了一个不存在的 Bean

如果我们在一个类中尝试注入一个不存在的 Bean,就会抛出 CouldNotAutowireField 的异常,如下所示。

@Service
public class UserService {
    @Autowired
    private Animal animal;
}

如果Animal这个类在容器中不存在,则会抛出异常。

五、总结

CouldNotAutowireField 这个异常很常见,但是一般情况下都能够通过仔细排查原因得到解决。应该学会从以下几个方面入手:注册 Bean、指定注入哪一个 Bean、注入不存在的 Bean。当然,还有其他一些可能导致该异常的原因,这需要根据具体情况具体分析。