@Named 或 @ManagedBean 注释通常用于让 bean 容器 (CDI/JSF) 在 JSF 中的表达式语言引用时按需创建 bean 的实例。
对于@Entity bean,仅仅获取一个任意的新实例通常没有多大意义。 @Entity 与持久身份的连接非常紧密。因此,此类实体是从 Entity Manager 请求的,而不是从 bean 容器请求的。
典型的模式是有一个(苗条的)支持 bean,该 bean 被命名为调用服务(在 Java EE 中通常是 @Stateless)。然后服务返回实体。
在一些非常琐碎的系统中,人们有时会为服务命名,从而直接对 EL 可用。但是,最终您通常希望让“支持代码”生成人脸消息或处理(表格)选择,这些都是纯业务服务不应该关注的事情。
另一个常见的捷径是让支持 bean 直接包含业务代码(例如,检索实体的实体管理器)。这使得业务代码难以重用,但如果应用程序很简单并且不需要重用,您可能会侥幸成功。
但是让实体作为支持 bean 是罕见的,并且与常见的 Java EE 模式相悖。
请注意,backing bean 可以直接返回实体,所以仍然可以使用 bean-validation。很久以前出现的奇怪的“分散/聚集”模式已经没有必要了(参见this question 中的第二个示例)。
例如
@ViewScoped
@ManagedBean
public class BackingBean {
private SomeEntity myEntity; // + getter
@EJB
private Service service;
@PostConstruct
public void init() {
myEntity = service.getSomeEntity();
}
public void save() {
service.save(myEntity);
FacesContext.getCurrentInstance().addMessage(..., ...);
}
}
假设 SomeEntity 在 @Entity 注释的 bean 中,bean 验证现在可以在 Facelet 上使用,例如:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
>
<h:body>
<h:form>
<h:inputText value="#{backingBean.myEntity.name}" />
<h:commandButton value="Save" action="#{backingBean.save}" />
</h:form>
</h:body>
</html>
如果对 SomeEntity.name 有限制,它将被验证。