2013-03-06 51 views
1

我是EJB技術的新手,我正在閱讀Oracle指南,試圖將我閱讀的內容付諸實踐。我在Eclipse中使用JBoss應用程序服務器創建了一個簡單的JSF應用程序,使用Managed Bean作爲支持Bean。我想通過Singleton Bean初始化Managed Bean中的數據,以感受依賴注入的工作方式。我遵循relevant instructions,但我無法設法初始化Singleton Bean。應用程序在Hello Managed Bean的構造函數中拋出一個NPE。我預計我的代碼可能缺少某些東西,但我無法找到它。以下Bean類中的缺陷在哪裏? :不能在EJB中應用依賴注入

@Startup 
@Singleton 
public class LaunchBean { 

private List<String> custs; 

public List<String> getCusts() { 
    return custs; 
} 

public void setCusts(List<String> emps) { 
    this.custs = emps; 
} 

@PostConstruct 
void init() {  //in the guide the() after init is missed, but the code does not compile when omitting it 
    custs = new ArrayList<String>(); 
    custs.add("Cust1"); 
    custs.add("Cust3"); 
    custs.add("Cust2"); 
    custs.add("Cust4"); 
} 

} 


@ManagedBean 
@SessionScoped 
public class Hello implements Serializable{ 
@EJB 
private LaunchBean dBean; 


private static final long serialVersionUID = 1L; 
private List<String> customers; 
private String customersSelect; 

public Hello(){ 
    customers = dBean.getCusts(); 
} 

public List<String> getCustomers() { 
    return customers; 
} 

public String getCustomersSelect() { 
    return customersSelect; 
} 

public void setCustomersSelect(String customersSelect) { 
    this.customersSelect = customersSelect; 
} 

} 

回答

2

@kostja, 託管bean位於Servlet上下文的頂部,因此您從CAN從託管Bean內部注入EJB。 @arjacsoh。您需要在@PostConstruct方法中包含代碼customers = dBean.getCusts();。你不能在構造函數中完成它,因爲這個managedbean還沒有被創建。在創建Bean之後立即執行@PostConstruct方法。

+0

從EJB 3.1開始,您無法使用'EJB'註釋來注入EJB [請參閱此問題](http://stackoverflow.com/questions/2021370/ejb-3-1-ejb-injection-into-pojo)。但是,您可以使用CDI或JNDI注入它們。至於'@ PostConstruct' - 我已經注意到這個問題太晚了,但是我已經在發佈答案之前發佈了建議,請參閱我的編輯。 – kostja 2013-03-06 11:13:08

+0

@Umoh - 我沒有製作ManagedBean EJB的意圖,但我仍然很好奇它是否可能。 JSF可以使用EJB作爲支持Bean嗎? – arjacsoh 2013-03-06 11:26:28

+0

@kostja。我審視了這個問題,它似乎更像是一場討論,而不是任何結論性的。我已經提出了選擇'@ PostConstruct'的答案。我仍然在編輯我的答案,所以我沒有看到它。儘管如此,我仍然不確定注入的事情。我會做更多的研究。 – greenkode 2013-03-06 11:29:50

4

您可以使用@EJB註釋將EJB注入到其他EJB中。 Hello bean不是一個EJB。 @ManagedBean@SessionScoped註釋都不能使其成爲一個。例如,您可以爲其添加@Stateless@Stateful註釋。

或者,您可以使用CDI使用@Inject批註將EJB注入非EJB。但是請注意,您將無法利用通過CDI注入的EJB bean來利用某些EJB功能。

編輯我剛剛注意到代碼的另一個問題。這不僅是注射是錯誤的。如果您嘗試在那裏訪問注入的成員,那麼在Hello bean的構造函數中總會有一個NPE。這些成員在構造對象後注入,因此對構造函數不可用。注射後儘快與注射成員一起使用,請使用注有@PostConstruct的方法。

編輯2我已經做了一些SO挖掘,它似乎像EJB注入indeed works for ManagedBeans。因此,儘管無法將EJB注入到帶有EJB批註的POJO中,但在這種情況下,ManagedBeans不會被視爲POJO :)。我很抱歉給您帶來不便。

+0

如果我添加註釋@Stateless或Stateful,但是可以將它用作支持Bean到JSF文件嗎?一般情況下,我可以使用哪些方法將Bean備份到JSF? – arjacsoh 2013-03-06 10:14:47

+0

@arjacsoh當然,一個EJB可以用作支持bean,沒有任何問題。這並不總是可能的,因爲JSF前端通常運行在沒有EJB支持的Tomcat之類的servlet容器上。但是,如果您的前端運行在Java EE應用服務器上 - 那就去做吧。 – kostja 2013-03-06 10:29:27

+0

我試過了(改爲無狀態),但它無法正常工作。它將ListBox清空,沒有數據。點擊按鈕移到下一頁後,它會拋出錯誤:=「#{hello.customersSelect}」:目標無法訪問,標識符'hello'解析爲空。 – arjacsoh 2013-03-06 10:39:21