You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CDI 4.0中@Specializes Bean未继承父类作用域?部署异常解析

问题背景

我们正将项目从JavaEE8升级至JakartaEE10(对应CDI 4.0),遇到以下部署异常问题:

  • 最终war包包含一个无beans.xml的隐式Bean归档JAR,其中定义了@Named("a")、@RequestScoped的类A
  • 主项目中通过@Specializes注解定义了继承A的类B,同时有@Named("c")、@RequestScoped的类C注入了B
  • 代码未改动,但在Java17+JakartaEE10环境下运行时抛出异常:
    org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type B with qualifiers @Default
    
  • 给B添加作用域注解后恢复正常;排查发现CDI 3.0到4.0默认Bean发现模式从ALL改为ANNOTATED,显式设置为ALL也可解决问题

核心疑问:@Specializes作为类级Bean注解,为何不属于Bean定义注解?

解答

首先明确CDI 4.0中ANNOTATED模式下的Bean定义注解范围:
CDI规范明确规定,只有能直接将一个类标记为CDI Bean的注解才属于Bean定义注解,具体包含:

  • 所有作用域注解(如@RequestScoped、@Singleton等)
  • @Named
  • @Alternative
  • @Interceptor
  • @Decorator

而@Specializes的定位是Bean修饰注解,它的作用是告知CDI:当存在继承关系时,用被@Specializes标记的子类Bean替代父类Bean的行为,但它本身不能单独将一个类定义为CDI Bean——也就是说,@Specializes必须依附于一个已经被Bean定义注解标记的类才能生效。

回到你的场景:
类A本身带有@Named和@RequestScoped(均为Bean定义注解),所以在任何发现模式下都会被识别为Bean;但类B只有@Specializes,没有任何Bean定义注解,在ANNOTATED模式下,CDI不会将B识别为合法Bean,因此注入B时会出现依赖找不到的异常。

两种可行的解决方式:

  1. 给类B添加一个Bean定义注解(比如你已经试过的作用域注解),让CDI在ANNOTATED模式下能识别它
  2. 将Bean发现模式改回ALL,让CDI扫描所有类并识别为Bean(与JavaEE8/CDI3.0的行为一致)

内容的提问来源于stack exchange,提问作者Steven De Groote

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 08:42:42