@ javax.annotation.ManagedBean是一个定义注释的CDI bean吗?

时间:2014-08-15 13:14:43

标签: dependency-injection cdi managed-bean glassfish-4 java-ee-7

问题

鉴于我们部署的档案是一个"隐式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有错误吗?

CDI 1.1第1部分

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

  

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

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

CDI规范部分2.5" Bean定义注释"表示:

  

任何范围类型都是定义注释的bean。

因此,根据CDI规范的这一部分,它的所有内容都是清楚的。如果我部署了一个没有beans.xml描述符文件的存档,那么只要它们具有显式声明的作用域{@ 3}},我就可以@Inject bean。它适用于WildFly和GlassFish。然而..

Managed Beans

Java EE技术堆栈中的所有规范必须遵守的子集规范Managed Beans(@javax.enterprise.context.RequestScoped)具有"基本模型"其中JSR-316确定了托管bean。托管bean规范并没有说@ManagedBean使得bean成为注入点(即字段或参数)的合理注入目标。规范确实说bean和#34;可以在Java EE应用程序的任何地方使用" (第MB.1.2节和第34节;为什么是管理豆?")在我耳边听起来应该是可以注射的。

Java EE 7 Umbrella规范

Java EE 7规范(@javax.annotation.ManagedBean)在EE.5.24"对依赖注入的支持":

中有这个说法。
  

容器必须支持带注释的注入点   javax.inject.Inject注释仅限于CDI规定的范围。每   CDI规范,托管支持依赖注入   豆。

     

目前有三种方法可以使类成为托管bean:

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

    满足至少一个这些条件的类将符合条件   用于CDI中描述的完全依赖注入支持   说明书

你去了:@ManagedBean有"完全依赖注入支持"。不是一半或只是一点点的支持。然而,我并不确定究竟是什么"依赖注入支持"是。但我认为下面的段落描述得足够好:

  

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

基本上,本段所说的是第二个条件 CDI托管bean,可以注入其他托管类(因为异常bean"也可以")。 / p>

伞形规范和托管bean规范都使得CDI规范有了明确的说法。

CDI 1.1第2部分

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

  

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

这句话无疑表示@ManagedBean可以用作注入点的目标而不添加范围类型的概念(JSR-342始终是默认值)。

如前所述,从WildFly中的隐式bean归档注入@ManagedBean,据我所知,这是刚引用的所有Java EE规范所要求的。所以我认为GlassFish有一个bug。但CDI规范从未在2.5节" Bean定义注释"中说过关于@ManagedBean的一句话,并且一如既往,在阅读重叠的Java EE规范时,我感到神经紧张,所以我想我应该先问一下我去提出一个关键的" GlassFish团队的错误。

编辑2014-08-22

提起了一个GlassFish错误:@Dependent

1 个答案:

答案 0 :(得分:3)

这不是一个完整的答案,因为当我们试图将所有规范放在一起并理解时,不可避免地会产生混淆。我只想说CDI 1.2已经澄清了一个bean定义注释的确切内容(参见“2.5.1.Bean定义注释”一节)。 CDI 1.2列出了一个清单:

  

定义注释的bean集包含:

     
      
  • @ApplicationScoped,@ SessionScoped,@ ConversationScoped和@RequestScoped annotations,
  •   
  • 所有其他正常范围类型,
  •   
  • @Interceptor和@Decorator annotations,
  •   
  • 所有刻板印象注释(即用@Stereotype注释的注释),
  •   
  • 和@Dependent范围注释。
  •   

应该补充的是,定义“正常范围类型”(第二个项目符号点)的内容是注释@NormalScope的自定义范围。