JSF管理bean EJB注入 [英] JSF managed-bean EJB injection
问题描述
我在企业应用程序模块中有一个EJB(PersonManager),它注入另一个EJB(Person):
@Stateful
public class PersonManager实现PersonManagerLocal {
@EJB
private PersonLocal person;
@Override
public void setPersonName(String name){
person.setName(name);
}
@Override
public String getPersonName(){
return person.getName();
}
}
我想在JSF网页中使用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。我怎么了?
但是,如果我将一个JSF管理的bean中的PersonManager注入到这个文件中:
@ManagedBean
@RequestScoped
public class Index {
@EJB
private PersonManagerLocal personManager;
....
IT WORKS。我需要第一种情况,请帮助我:-D
您正在混合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
换句话说,您正在将该类注册为JSF托管的bean,该bean可以通过
@SessionScoped
public class PersonManager {
// ...
}
#{personManager}
。这不代表与EJB容器管理的实例相同的实例。您可以并且应该不使用faces-config.xml
注册EJB。您可以使用javax.ejb
包中的注释,例如@Stateless
和@Stateful
。这就是注册一个EJB所需要的。
实际上,在
faces-config.xml
中注册JSF托管bean是JSF 2.x中的旧JSF 1.x方式已被新的@ManagedBean
注释所取代。
更新 p>
< h:form>
< h:inputText value =#{personManager.person.name}/>
...
< h:commandButton value =保存action =#{personManager.save}/>
< h:messages />
< / h:form>
控制器(JSF托管bean):
@ManagedBean
@ViewScoped
public class PersonManager implements Serializable {
private Person person;
@EJB
私人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()));
}
// ...
}
Model(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);
}
// ...
}
I have an EJB (PersonManager) in the Enterprise Application modul, which injects another 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(); } }
I want to use the PersonManager EJB in a JSF web app. I define it in the 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>
The problem is that, the injection of the PersonLocal EJB doesn't happen. The person property is always NULL. What did I wrong?
But if I inject the PersonManager in a JSF managed bean like this:
@ManagedBean @RequestScoped public class Index { @EJB private PersonManagerLocal personManager; ....
IT WORKS. I need the first scenario, please help me :-D
解决方案You are mixing the responsibilities of EJBs and JSF managed beans. The
faces-config.xml
registers only JSF artifacts, such as managed beans and not EJBs. Your registration infaces-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>
does basically exactly the same as
@ManagedBean @SessionScoped public class PersonManager { // ... }
In other words, you're registering the class as a JSF managed bean which is available in views by
#{personManager}
. This does not represent the same instance as is managed by the EJB container. You can and should not usefaces-config.xml
to register EJBs. There you use the annotations from thejavax.ejb
package for, such as@Stateless
and@Stateful
. That's all you need to register an EJB.Actually, registering JSF managed beans in
faces-config.xml
is an old JSF 1.x way which has in JSF 2.x been replaced by the new@ManagedBean
annotation.
Update the proper approach would be:
View (the Facelets file):
<h:form> <h:inputText value="#{personManager.person.name}" /> ... <h:commandButton value="Save" action="#{personManager.save}" /> <h:messages /> </h:form>
Controller (the JSF managed 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())); } // ... }
Model (the JPA entity):
@Entity public class Person implements Serializable { @Id private Long id; private String name; // ... }
Service (the stateless EJB):
@Stateless public class PersonService { @PersistenceContext private EntityManager em; public void create(Person person) { em.persist(person); } // ... }
这篇关于JSF管理bean EJB注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!