为何bean-discovery-mode为annotated时@Dependent非默认作用域?
问题解析:CDI/Weld中
bean-discovery-mode=annotated时无注解Bean无法注入的原因 核心结论
无注解的TestBean在bean-discovery-mode=annotated时无法被注入,不是因为@Dependent不再是默认作用域,而是这个类根本没被CDI容器识别为Bean。
1. Bean发现规则与默认作用域的关系
- @Dependent确实是CDI规范中所有Bean的默认作用域,但这个规则的前提是:该类已经被容器认定为一个Bean。
- 当
bean-discovery-mode=all时:
容器会扫描归档内所有符合基础条件的类(非抽象、非内部类、非Java EE规范自带类等),将它们全部视为Bean,此时无注解的TestBean会被自动赋予@Dependent作用域,所以能正常注入,且因为@Dependent是伪作用域,不会生成代理。 - 当
bean-discovery-mode=annotated时:
容器只会识别带有Bean定义注解的类。Bean定义注解包括:- 所有作用域注解(@Dependent、@RequestScoped、@SessionScoped等)
- @Named、@Interceptor、@Decorator等CDI专用注解
- EJB相关注解(@Singleton、@Stateless等)
你的TestBean没有任何上述注解,因此不会被容器当作Bean,自然不存在默认的@Dependent作用域,注入时就会抛出WELD-001408依赖未满足错误。
2. 隐式Bean归档的判定逻辑
根据Weld 3.1文档,隐式Bean归档的判定条件是:
包含一个或多个带有Bean定义注解的Bean类、或一个或多个会话Bean的归档;也可以是包含版本1.1及以上、bean-discovery-mode为annotated的beans.xml文件的归档。
对于无beans.xml的归档:
- 默认
bean-discovery-mode=annotated,但它要成为隐式Bean归档,必须满足归档内存在带有Bean定义注解的类。 - 你的场景中,
TestBean无任何注解,所以这个归档不符合隐式Bean归档的条件,容器不会扫描其中的类来发现Bean。只有当你给TestBean添加@Dependent(或其他Bean定义注解)后,归档内才有了符合条件的Bean类,此时才会被认定为隐式Bean归档,容器才会识别TestBean并赋予默认/显式的作用域。
验证代码回顾
你的测试代码:
@WebServlet("/proxy") public class ProxyServlet extends HttpServlet { @Inject private TestBean testBean; } public class TestBean { }
bean-discovery-mode=all:TestBean被识别为@Dependent Bean,可正常注入bean-discovery-mode=annotated:TestBean无Bean定义注解,不被识别为Bean,注入失败- 添加@Dependent注解后:
TestBean成为带有Bean定义注解的类,被容器识别为Bean,恢复正常
内容的提问来源于stack exchange,提问作者ericj
相关产品推荐
相关产品推荐

