Java EE 6 和 CDI

Posted

技术标签:

【中文标题】Java EE 6 和 CDI【英文标题】:Java EE 6 and CDI 【发布时间】:2011-10-15 07:02:28 【问题描述】:

我刚开始学习 CDI 和 Java EE 6,但我发现这段代码我想完全理解。

@Stateful
@Model
public class MemberRegistration 
   @Inject
   private EntityManager em;

   @Inject
   private Event<Member> memberEventSrc;

   private Member newMember;

   @Produces
   @Named
   public Member getNewMember() 
      return newMember;
   

然后...我看到一个 jsf 页面引用了这个 newMember 对象,如下所示:

<h:inputText value=#newMember.name/>

所以我的问题是:如果我将 @Named 注释放在任何对象的变量中都没关系,无论如何都可以从 JSF 代码访问它? 另外,在这种情况下@Produces 的用途是什么,最后在 Java EE 6 中@Stateful 优于@Stateless?如果是这样,为什么呢?

【问题讨论】:

【参考方案1】:

尽管它很简单,但这个 bean 确实可以做很多事情 ;)

@Named (CDI) 或 @ManagedBean (JSF-native) 注解是让 JSF 知道 bean 所必需的。但是,Java EE 有stereotypes 的概念,这是一种结合了许多其他注解的复合注解。

在这种情况下@Model 就是这样一个刻板印象,它结合了@Named@RequestScoped

@Produces注解了一个工厂方法;一种知道从哪里获取某种类型的实例的方法。它可以与所谓的限定符注释结合使用,例如@Foo,之后您可以使用该注解在某个 bean 中注入一些东西。但是在这种情况下,它与@Named 结合使用,这使得newMember 可用于JSF。而不是创建bean时会发生例如首先遇到@RequestScoped bean,当JSF 需要实例时,将调用getNewMember() 方法。请参阅Dependency Injection in Java EE 6 了解更多信息。

@Stateful 在独立使用时通常不优于@Stateless@Stateless bean 被池化并为客户端执行一种方法(通常在事务上下文中)。它们的有状态对应物没有池化并且没有 CDI,调用者必须跟踪其生命周期(通过最终调用 @Remove 注释方法)。在这里,bean 也被分配了一个范围(请求,通过@Model),所以容器会处理这个。

在这里使用这个注解的可能原因可能是使 bean 的方法具有事务性。虽然给定的片段没有显示它的用法,但我猜这个类的一个版本有更多使用EntityManager 的方法。交易将在那里发挥作用。

(注意,以这种方式组合注解为 Java EE 开发人员提供了很大的权力,但它确实在一个 bean 中放置了几个问题,这与 bean 应该做一件事并做好这件事的口头禅相反。一个替代方案是 @Model 注释 bean,仅关注视图问题,它注入了封装业务逻辑的 @Stateless bean,而不是 EntityManager。)

【讨论】:

以上是关于Java EE 6 和 CDI的主要内容,如果未能解决你的问题,请参考以下文章

构建 Java EE 6 项目时出现 FilerException

使用 java EE 6 注释的 Servlet 过滤?

Java EE 6 安全性和重定向

Java EE 6:@Inject 和 Instance<T>

程序化 Java EE 6 登录:如何捕获 LoginException?

在 Java EE 6 中制作 Java Web 应用程序需要学习啥? [关闭]