由于CDI/Weld中的@Named,@ ManagedBeans在JavaEE6中是否已过时?

Ing*_*her 41 jsf java-ee jsf-2 jboss-weld

由于CDI(及其实现Weld),JEE6中的每个POJO都可以注释@Named,这使得POJO可以被视图访问.

这是否意味着ManagedBeans现在已经完全过时了?还是我错过了@ManagedBean仍然有意义的东西?

Pas*_*ent 51

简而言之,@ManagedBean对于使用JSF但不使用JSR 299的应用程序有意义(无论原因是什么).下面是Gavin King的更长解释:

Re:比较JSF2中的@ManagedBean注释?:

在查看Weld示例和较旧的WebBeans文档时,它看起来像是新的@ManagedBean JSF 2.0注释的竞争对手.有关何时我们想要使用其中一个的信息?

这是一个很好的问题,我并不完全同意迄今为止发布的答案.

新EE管Bean规范定义的Java EE基座组件模型,具有非常组基本的容器服务(一起@Resource, @PostConstruct,@PreDestroy).

这个想法是其他规范(从EJB,CDI,JSF和新的Java拦截器规范开始)构建在这个基本组件模型和层附加服务上,例如事务管理,类型安全依赖注入,拦截器.因此,在这个级别,托管bean,CDI,拦截器和EJB规范都是相辅相成的,并且是高度互补的.

现在,Managed Beans规范在确定哪些类是托管bean时非常开放.它确实提供了 @ManagedBean注释作为一种机制,但它也允许其他规范定义不同的机制.所以,例如:

  • EJB规范说,遵循EJB jar中部署的@Stateless或者 @Stateful注释的某些编程限制的类是托管bean.

  • CDI规范说任何具有在"bean部署档案"中部署的适当构造函数的类都是托管bean.

鉴于EJB和CDI可以提供更方便的方法来识别托管bean,您可能想知道究竟@ManagedBean需要什么.Dan提到的答案是,如果您的环境中有CDI(例如,如果您使用的是EE6),那么 @ManagedBean就不需要了.@ManagedBean是真的有没有CDI使用JSF2的人使用.

OTOH,如果你注释bean @ManagedBean,并且你的环境中确实有CDI,你仍然可以使用CDI将东西注入你的bean.只是在这种情况下不需要@ManagedBean 注释.

总之,如果你有提供给你CDI,它提供了一个远远 优于编程模型到 @ManagedBean/ @ManagedProperty模型JSF2从JSF1继承.事实上,EE 6 Web配置文件不需要支持 @ManagedProperty等等.这个想法是你应该只使用CDI.


Bri*_*hem 15

你有一个选择.使用JSF2中的@ManagedBean将bean绑定到表单中,或者使用CDI中的@Named注释.如果你只打算做JSF,你可以坚持@ManagedBean,但是如果你想与EJB集成,或者使用CDI的@ConversationScoped,那么就去CDI路线.

就个人而言,我觉得下一版本的JSF应该弃用@ManagedBean,并在CDI上标准化.二元性让新人感到困惑.


Kaw*_*awu 10

CDI没有视图范围,因为它没有视图的概念,所以如果你需要那个范围,那么纯粹形式的CDI就无法做到.视图范围基本上意味着请求范围+准备好AJAX.这不是一个JSF视图,就像一个名为的页面xyz.xhtml,即使你看到JSF <f:viewParam>等.视图范围bean的常见用例是如何将GET参数转换为这样的bean.还读这个.

请注意,CDI比JSF /表示层更适用于EJB /服务层.这个博客有一个很好的概述.

因此@ManagedBean,如果您正在使用@ViewScopedbean ,则无法完全取代CDI - 至少在没有扩展CDI或使用Seam 3 Faces模块的情况下也是如此.使用基于AJAX的基于JSF 2的GUI工具包(如RichFaces,PrimeFaces,IceFaces等)时,几乎总会发生使用视图范围的bean.

混合从错误的Java EE 6的包注释可以使用RichFaces的或类似的API时给你带来麻烦意外,再次:

@javax.faces.bean.ManagedBean
@javax.faces.bean.[Jsf]Scoped
Run Code Online (Sandbox Code Playgroud)

用于在表示层使用的组件,这里是RichFaces,PrimeFaces等.一些富组件似乎有CDI注释和JSF注释的助手bean的问题.如果你从你的bean(或似乎什么都不做的bean)中得到奇怪的行为,那么错误的注释组合可能就是原因.

混合JSF和CDI,比如

@javax.inject.Named
@javax.faces.bean.[Jsf]Scoped
Run Code Online (Sandbox Code Playgroud)

在大多数情况下从JSF页面引用时都可以使用,但是有一些鲜为人知的问题/缺点,例如在使用CDI没有的JSF范围时:

此组合@Named @ViewScoped也无法按预期工作.特定@ViewScoped于JSF的工作@ManagedBean仅与JSF相关.您的CDI特定@Named行为将@RequestScoped如此.或者使用@ManagedBean替代@Named,或者使用专用CDI @ConversationScoped代替@ViewScoped.

然后

@javax.inject.Named
@javax.faces.bean.[Cdi]Scoped
Run Code Online (Sandbox Code Playgroud)

可以用于直接从JSF页面AFAIK引用的CDI bean.到目前为止,我对上述组合没有任何问题,所以你可以考虑@ManagedBean在这里过时.

剩下的是服务层,这里主要是事务性EJB服务bean,声明为

@javax.ejb.*
Run Code Online (Sandbox Code Playgroud)

主要是@ javax.ejb.Stateless.您甚至可以直接从JSF页面注释和使用EJB - 尽管我不确定这种设计是否合适.引用(注入)使用@ javax.ejb.*注释的任何组件,例如@Stateless,优先@Inject@EJB 此处所述.(可能是这个答案的祖先......)

最后,可以在此处找到Java EE 6注释的非常好的概述:http: //www.physics.usyd.edu.au/~rennie/javaEEReferenceSheet.html

注意:上面的信息不是来自专家,而只是我自己从新手的角度看待这个令人难以置信的混乱的Java EE 6注释意大利面.还有待开发更多见解.我希望这个答案能够成为解决这种混乱的一般而实际的答案 - 即使它在原始问题的背景下有点过分.


Ing*_*her 7

正如我刚刚阅读Weld参考文献(第12页),@ ManagedBean现在是超级丰富的:

您可以通过注释bean类@ManagedBean来显式声明托管bean,但是在CDI中您不需要.根据规范,CDI容器将满足以下条件的任何类视为托管bean:

  • 它不是一个非静态的内部类.它是一个具体的类,或者注释为@Decorator.
  • 它没有使用EJB组件定义注释或在ejb-jar.xml中声明为EJB bean类.
  • 它没有实现javax.enterprise.inject.spi.Extension.
  • 它有一个合适的构造函数 - 或者:
  • 该类有一个没有参数的构造函数,或者
  • 该类声明一个注释为@Inject的构造函数.