JSF 托管 bean EJB 注入
Posted
技术标签:
【中文标题】JSF 托管 bean EJB 注入【英文标题】:JSF managed-bean EJB injection 【发布时间】:2012-01-27 10:01:32 【问题描述】:我在企业应用程序模块中有一个 EJB(PersonManager),它注入另一个 EJB(Person):
@Stateful
public class PersonManager implements PersonManagerLocal
@EJB
private PersonLocal person;
@Override
public void setPersonName(String name)
person.setName(name);
@Override
public String getPersonName()
return person.getName();
我想在 JSF Web 应用程序中使用 PersonManager EJB。我在 faces-config.xml 中定义它:
<managed-bean>
<managed-bean-name>personManager</managed-bean-name>
<managed-bean-class>ejb.PersonManager</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
问题在于,不会发生 PersonLocal EJB 的注入。 person 属性始终为 NULL。我做错了什么?
但是如果我像这样将 PersonManager 注入到 JSF 托管 bean 中:
@ManagedBean
@RequestScoped
public class Index
@EJB
private PersonManagerLocal personManager;
....
它工作正常。我需要第一个场景,请帮帮我:-D
【问题讨论】:
为什么不用@EJB注解代替在faces-config.xml中手动声明呢?这就像在没有发明注释时试图回到过去:P 你是对的 :-D 这只是理论上的,我想知道答案。 @Forty 那么为什么它不起作用呢?我不清楚答案。 【参考方案1】:您正在混合 EJB 和 JSF 托管 bean 的职责。 faces-config.xml
仅注册 JSF 工件,例如托管 bean 而不是 EJB。您在faces-config.xml
注册
<managed-bean>
<managed-bean-name>personManager</managed-bean-name>
<managed-bean-class>ejb.PersonManager</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
和
基本一模一样@ManagedBean
@SessionScoped
public class PersonManager
// ...
换句话说,您正在将该类注册为一个 JSF 托管 bean,#personManager
可以在视图中使用它。这并不代表由 EJB 容器管理的同一实例。您可以并且应该不使用faces-config.xml
注册EJB。在那里,您可以使用 javax.ejb
包中的注释,例如 @Stateless
和 @Stateful
。这就是注册 EJB 所需的全部内容。
实际上,在 faces-config.xml
中注册 JSF 托管 bean 是一种旧的 JSF 1.x 方式,在 JSF 2.x 中已被新的 @ManagedBean
注解取代。
更新正确的方法是:
查看(Facelets 文件):
<h:form>
<h:inputText value="#personManager.person.name" />
...
<h:commandButton value="Save" action="#personManager.save" />
<h:messages />
</h:form>
控制器(JSF 托管 bean):
@ManagedBean
@ViewScoped
public class PersonManager implements Serializable
private Person person;
@EJB
private PersonService personService;
@PostConstruct
public void init()
person = new Person();
public void save()
personService.create(person);
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Person successfully created, new ID is " + person.getId()));
// ...
模型(JPA 实体):
@Entity
public class Person implements Serializable
@Id
private Long id;
private String name;
// ...
服务(无状态 EJB):
@Stateless
public class PersonService
@PersistenceContext
private EntityManager em;
public void create(Person person)
em.persist(person);
// ...
【讨论】:
谢谢,PersonManager 是一个业务 EJB,因此不包含 @ManagedBean 注释。它是由 JSF 引擎创建的,只是在 faces-config 场景下没有将 person EJB 注入其中。 我知道 EJB 是什么以及应该如何使用它们。你?究竟是哪一部分现在还不清楚? 请注意,我的答案示例中缺少@Stateful
。它不是这样的 EJB。您试图将 EJB 滥用为 JSF 托管 bean。这个不对。您基本上应该有 1 个 Xhtml 文件作为视图,1 个 JSF 托管 bean 作为控制器,1 个实体作为模型和 1 个 EJB 作为服务。在您的问题中,PersonManager
应该是 JSF 托管 bean,而不是 EJB。 PersonLocal
似乎是一个实体,而不是 EJB。所以我怀疑它是否真的需要成为 EJB。 EJB 旨在提供create()
、save()
等服务。
另请参阅更新的答案以获取启动示例。请注意,您根本不需要配置 xml 文件。
我在看答案的同时也很佩服作者,但是当我读到最后,看到底部有你的名字“BalacC”,我的兴奋感降低了。难怪只有你能写出这么好的答案。祝你好运以上是关于JSF 托管 bean EJB 注入的主要内容,如果未能解决你的问题,请参考以下文章
将 JSF2 托管 pojo bean 传递到 EJB 或将所需内容放入传输对象
Spring JSF 集成:如何在 JSF 托管 bean 中注入 Spring 组件/服务?
使用@EJB 时,每个托管bean 是不是都有自己的@EJB 实例?
Managed Bean中的EJB3.0 @EJB注释JSF2 Websphere 7是不可能的?