是@javax.annotation.一个CDI bean定义注释



问题

假设我们部署的存档是一个"隐式bean存档"(见下文),使用@javax.inject.Inject@javax.annotation.ManagedBean注入到WildFly 8.1.0中的另一个托管bean工作中,但它不会在GlassFish 4.0.1-b08和GlassFish 4.1-b13中工作。GlassFish崩溃,显示如下信息:

WELD-001408:类型…不满足依赖

是我误解了以下概述的规范,还是GlassFish有bug?

CDI 1.1 Part 1

CDI 1.1 (JSR-346)第12.1节"Bean Archives"说:

显式bean归档是包含beans.xml文件的归档[…]。隐式bean归档是包含一个bean的任何其他归档或者更多带有bean定义注释的bean类[…]。

如果这样,我的存档没有beans.xml描述符文件,我仍然能够使用具有"bean定义注释"的bean。问题是,什么是bean定义注释?

CDI规范第2.5节"Bean定义注释"说:

任何作用域类型都是bean定义注释。

这是非常清楚的,根据CDI规范的这一部分,这就是它的全部内容。如果我部署的归档文件中没有beans.xml描述符文件,那么只要bean具有显式声明的作用域(例如@javax.enterprise.context.RequestScoped),我就可以@Inject bean。它适用于WildFly和GlassFish。然而. .

托管bean

Java EE技术栈中的所有规范都必须遵守的子集规范,托管bean (JSR-316),具有一个"基本模型",其中@javax.annotation.ManagedBean确实定义了一个托管bean。托管bean规范并没有说@ManagedBean使bean成为注入点(即字段或参数)的合理的注入目标。规范确实说bean"可以在Java EE应用程序的任何地方使用"(章节MB.1.2"为什么要管理bean ?"),在我看来,它们也应该是可注入的。

Java EE 7 Umbrella规范

Java EE 7规范(JSR-342)在EE.5.24节"对依赖注入的支持"中有这样的说明:

容器必须支持用仅在CDI指定的范围内注入注释。每在CDI规范中,托管依赖注入是受支持的豆子。

目前有三种方法使类成为受管bean:

  1. 作为EJB会话bean组件。
  2. 使用ManagedBean注释进行注释。
  3. 满足CDI规范中描述的条件。

至少满足其中一个条件的类才有资格以获得CDI中描述的完全依赖注入支持规范。

好了:@ManagedBean有"完全依赖注入支持"。不是一半,也不是一点点支持。然而,我不确定"依赖注入支持"到底是什么。但我认为下面的段落已经很好地描述了它:

表EE.5-1中列出的满足第三个条件的组件类上述条件,但第一个和第二个条件都不能如果用CDI进行了注释,也可以用作CDI管理beanbean定义注释或包含在bean归档文件中,CDI为其定义注释启用。但是,如果将它们用作CDI管理bean(例如,注入到其他托管类中),即被管理的实例由CDI管理的实例可能不是由Java EE管理的实例容器。

基本上,这段话说的是第二个条件CDI托管bean可以被注入到其他托管类中(因为异常bean"也可以")。

伞形规范和托管bean规范都在一定程度上表明,CDI规范拥有最终决定权。

CDI 1.1 Part 2

@ManagedBean注释在CDI规范中只被提及两次,这两次都出现在第11章中,这一章讲述了CDI扩展可以观察到的生命周期CDI事件。第11.5.7节定义了一个ProcessInjectionPoint事件。托管bean可以使用依赖注入——这并不奇怪。但是,第11.5.8节定义了ProcessInjectionTarget事件。以下是规范对ProcessInjectionTarget事件的说明:

容器必须为每个Java EE组件类触发一个事件支持可以被容器实例化的注入运行时,包括使用@ManagedBean声明的每个托管bean, EJB会话或消息驱动bean、bean、拦截器或装饰器。

这句话毫无疑问地表明,@ManagedBean可以用作注入点的目标,而无需添加作用域类型的概念(@Dependent总是默认的)。

如前所述,从隐式bean存档中注入@ManagedBean在WildFly中工作,据我所知,这是刚才引用的所有Java EE规范所要求的。所以我认为是GlassFish有问题。但是CDI规范在2.5节"Bean定义注释"中从来没有提到@ManagedBean,而且和往常一样,当我阅读重叠的Java EE规范时,我总是很紧张,所以我认为我应该在向GlassFish团队提交一个"严重"错误之前问一下。

编辑2014-08-22

提交了一个GlassFish bug: https://java.net/jira/browse/GLASSFISH-21169.

这不是一个完整的答案,因为当我们试图把所有规范放在一起并弄清楚它们的意义时,不可避免地会出现混乱。我只是想说,CDI 1.2已经澄清了bean定义注释的确切含义(参见"2.5.1"节)。Bean定义注释")。CDI 1.2给出一个列表:

bean定义注解集包含:

  • @ApplicationScoped, @SessionScoped, @ConversationScoped和@RequestScoped注释,
  • 所有其他正常作用域类型,
  • @Interceptor和@Decorator注释,
  • 所有的原型注释(即用@Stereotype注释的注释),
  • 和@Dependent作用域注释

应该补充的是,定义"正常作用域类型"(第二个要点)的是一个标注了@NormalScope的自定义作用域。

相关内容

  • 没有找到相关文章

最新更新