我想知道,是否有任何选项可以在EJB bean中调用托管bean。想象一下,我们有代码:
@ManagedBean
@SessionScoped
public class MyManagedBean implements Serializable {
public String getUrl() {
return "http://www.google.com";
}
}
@Stateless
public class MyEJB {
@ManagedProperty(value = "#{myManagedBean}")
MyManagedBean myManagedBean;
public void setMyManagedBean(MyManagedBean myManagedBean) {
this.myManagedBean = myManagedBean;
}
public void call() {
// NullPointerException here
System.out.println(myManagedBean.getUrl());
}
}
我也试过这个:
@Stateless
public class MyEJB {
@EJB
MyManagedBean myManagedBean;
...
}
...但它会返回不同的MyManagedBean
实例。
答案 0 :(得分:3)
这是不对的。使用CDI托管bean而不是JSF托管bean,这是可能的,但它不是正确的,糟糕的设计。业务服务根本不应该了解前端。它使得业务服务在其他前端无法使用,而不是JSF。
你应该反过来做。您应该在托管bean中注入EJB,而不是相反。 EJB应该完全无状态。您应该直接向EJB传递它需要的信息作为方法参数(并且从不之后将其作为EJB的实例变量分配)。
E.g。
@ManagedBean
@SessionScoped // <-- Did you read https://stackoverflow.com/q/7031885?
public class MyManagedBean implements Serializable {
private String url = "http://www.google.com";
@EJB
private MyEJB myEJB;
public void submit() {
myEJB.call(url);
}
public String getUrl() {
return url;
}
}
和
@Stateless
public class MyEJB {
public void call(String url) {
// No NullPointerException here.
System.out.println(url);
}
}