我刚刚开始学习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
?如果是这样,为什么呢?
尽管它很简单,但这个bean确实做了很多事情;)
要使bean为JSF所知,需要@Named
(CDI)或@ManagedBean
(JSF本机)注释。然而,Java EE有stereotypes
的概念,这是一种组合了许多其他注释的组合注释。
在这种情况下@Model就是这样一个构造型,它结合了@Named
和@RequestScoped
。
@Produces
注释了一个工厂方法;知道从哪里获取某种类型的实例的方法。它可以与所谓的限定符注释(例如@Foo
)结合使用,之后您可以使用该注释在某个bean中注入某些内容。然而,在本例中,它与@Named
结合使用,使newMember
对JSF可用。当首先遇到@RequestScoped
bean时,就会创建bean,而在底层,当JSF需要实例时,将调用getNewMember()
方法。更多信息请参见Java EE 6中的依赖注入。
单独使用时,@Stateful
通常不优于@Stateless
。@Stateless
bean被池化并为客户端执行一个方法(通常在事务上下文中)。它们的有状态的对等物没有池化,没有CDI,调用者必须跟踪其生命周期(通过最终调用@Remove
注释的方法)。在这里,bean还被分配了一个作用域(通过@Model
请求),因此容器将负责这一点。
在这里使用这个注释的可能原因是使bean的方法具有事务性。尽管给出的片段没有显示它的用法,我猜这个类的一个版本有更多的方法利用EntityManager
。交易将在那里发挥作用。
(注意,以这种方式组合注释为Java EE开发人员提供了许多功能,但它确实在一个bean中放置了几个关注点,这与bean应该只做一件事并把它做好的咒语相反。另一种选择是@Model
注释bean,它只关注视图关注点,它被注入了封装业务逻辑的@Stateless
bean,而不是EntityManager
。