unsatisfieddependencyexception只是“报警信封”,真正病根在堆栈末尾caused by里;需逐层定位nosuchbeandefinitionexception、nouniquebeandefinitionexception等根因,并检查bean定义、扫描范围、注入匹配及特殊机制(如constraintvalidator、循环依赖)问题。

看到 UnsatisfiedDependencyException 别急着改代码,它只是“报警信封”,真正的病根藏在堆栈末尾的 Caused by 里。绝大多数问题几分钟内就能定位到具体类或字段。
盯紧堆栈最底下的 Caused by
Spring 启动失败时,控制台输出的异常堆栈往往很长。你真正要关注的是最后一段 Caused by,比如:
-
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.service.UserService' available→ 表明 UserService 这个 Bean 根本没注册进容器 -
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'PaymentService' available: expected single matching bean but found 2→ 接口有多个实现,Spring 不知道该选哪个 -
Caused by: java.lang.NullPointerException(出现在自定义 ConstraintValidator 中)→ 验证器不是由 Spring 创建的,@Autowired不生效
检查目标类是否被 Spring 管理
确认你要注入的那个类,本身是不是 Spring Bean:
- 类上有没有加
@Component、@Service、@Repository或@Controller?没有注解,Spring 就不会管它 - 主启动类所在包路径是否覆盖目标类?Spring Boot 默认只扫描主类所在包及其子包。如果
UserService在com.example.service,而主类在com.myapp,那就扫不到 - 需要跨包扫描?用
@ComponentScan(basePackages = {"com.example.service"})显式声明 - 是通过
@Configuration + @Bean定义的?确认配置类本身被扫描到了,且方法返回类型和注入点类型一致
核对注入点与候选 Bean 的匹配关系
即使目标类是 Bean,也可能因类型不匹配而注入失败:
- 接口有多个实现类?用
@Qualifier("beanName")指定具体 Bean,或用@Primary标记首选项 - 用了构造器注入,但构造器参数类型模糊?比如参数是
Object或泛型擦除后无法识别,建议用具体类型 - 注入的是原型(
@Scope("prototype"))Bean 到单例中?技术上可行,但要注意线程安全和状态共享问题 - 涉及 JPA 查询 DTO 构造?JPQL 中
SELECT new XxxDto(...)要求 DTO 有对应参数顺序的 public 构造器,否则会抛QueryCreationException,进而触发依赖注入链路中断
特殊场景要单独处理
有些注入失败不是常规流程导致的,得按机制来:
-
ConstraintValidator:Hibernate Validator 自己创建验证器实例,
@Autowired失效。必须配SpringConstraintValidatorFactory,让 Spring 接管验证器生命周期 -
循环依赖:A 依赖 B,B 又依赖 A。Spring 默认只支持单例间的 setter/field 注入,构造器注入会直接失败。可用
@Lazy延迟加载其中一个,或重构拆解依赖 -
编译期就报错(如
cannot find symbol):这不是 Spring 的事,是 Java 编译器找不到类。先补import,再确认包路径是否被@ComponentScan覆盖











