Quarkus使用Spring兼容扩展时模块注入报Unsatisfied dependency问题
Spring Boot 迁移 Quarkus JVM 模式 CDI 依赖缺失问题排查
核心报错原因
你遇到的Arc校验报错本质是Quarkus构建时CDI容器的校验逻辑和Spring运行时扫描逻辑的差异导致的:Arc会在构建阶段完成所有Bean的注册、依赖匹配校验,不会像Spring那样在应用启动运行阶段才做全量Bean解析,只要构建阶段找不到对应类型的可注入Bean,就会直接抛出Unsatisfied dependency异常,不会留到运行时。
对应你的几个疑问的说明
- 关于Jandex索引的作用:Jandex仅负责让构建工具能扫描到对应模块下的类和类上的注解,不会自动把扫描到的类全部注册为可注入Bean。只有类上带了Arc能识别的Bean定义注解(包括Spring兼容的
@Component/@Service/@Repository/@Configuration,或是CDI原生的作用域注解),才会被注册到容器里。 - 关于加
@ApplicationScoped也修不好的单独特例:基本逃不出三个原因:- 报错的类型是接口/抽象类,它的实现类没有被容器扫描注册
- 类没有可用于注入的构造函数(要么没有无参构造,要么带参数的构造函数没加
@Inject/@Autowired注解,且构造参数本身也有依赖缺失) - 这个类原本是通过Spring的
@Bean方法、自定义Bean注册扩展点动态注册的,你直接给实现类加注解不生效,因为注入点要求的类型可能和注册的Bean类型不匹配
- 关于quarkus-spring-*扩展的覆盖边界:这些扩展只适配了Spring核心注解的语义、常用自动配置逻辑,不会100%覆盖Spring所有的扩展能力。比如自定义
BeanDefinitionRegistryPostProcessor、FactoryBean、XML配置、复杂的条件注解判断,这些扩展默认是不支持的,通过这类方式注册的Bean不会被Arc自动识别。 - 关于只有少部分类报注入错:能正常注入的类基本都是直接标了Spring标准
@Service/@Component等原型注解,被扩展直接识别注册了;出问题的类都是通过非标准注解方式注册的——比如通过自定义注册器、XML、条件注解判断后注册、用了自定义派生注解,所以没被Arc扫到。
遗漏的适配检查步骤
- 逐个核对报错类的原始注册方式
- 如果是类上直接标注解注册的,确认注解是Spring原生
org.springframework.stereotype包下的标准注解,不要用项目自定义的派生复合注解,Quarkus对自定义派生注解的识别需要额外配置,默认不认 - 如果是通过
@Bean方法在配置类里注册的,先确认对应的配置类本身被容器识别成了Bean(即配置类上的@Configuration注解能被扫描到) - 如果是通过Spring SPI、自定义Bean注册器动态注册的,不用硬改原代码,写个CDI Producer方法手动注册对应Bean即可,尽量减少原有代码改动
- 如果是类上直接标注解注册的,确认注解是Spring原生
- 检查条件注解适配问题
Quarkus的Spring兼容扩展对Spring Boot的@Conditional*系列注解支持不全,如果报错类带了@ConditionalOnClass/@ConditionalOnMissingBean这类注解,很容易在构建阶段判断条件不成立,跳过Bean注册。可以先在配置里加quarkus.arc.remove-unused-beans=false关闭构建阶段未使用Bean自动移除逻辑,再逐个排查条件判断问题。 - 定位单个修复失败的问题根因
给那个加了@ApplicationScoped也没用的类开构建debug日志:在application.properties里加quarkus.arc.dependency-resolution-failure.debug=true,构建时会打印出该类型所有被扫描到的候选Bean,以及每个候选不满足注入要求的具体原因,不用瞎猜。 - 检查XML配置支持
如果你的项目里有用Spring XML配置注册Bean,必须额外引入quarkus-spring-xml扩展,默认是不解析XML里的Bean定义的。
小提示:JVM模式下不用强行把所有Spring注解替换成CDI原生注解,只要能让Arc识别到Bean定义即可,优先用无侵入的适配方式,符合你最小改动跑通应用的目标。
内容的提问来源于stack exchange,提问作者msfbrasil
相关产品推荐
相关产品推荐

