2013-02-23 50 views
1

遠程接口我有一個這樣的接口:訪問企業Bean通過與@EJB

@Remote 
public interface ClientDataAccessRemote 

和EJB實現它:

@Stateless 
public class ClientDataAccess implements ClientDataAccessRemote 

而在遠程客戶端,我可以訪問EJB與此:

@EJB 
private static ClientDataAccessRemote clientDataAccess; 

這是我所做的一切,它的工作原理。客戶端和EJB駐留在同一臺服務器上。如果他們分開,它仍然會工作嗎?容器如何通過該接口找到EJB?我使用Netbeans實現了這一點,並且我不必指定任何位置或類似的東西。這個怎麼用?

回答

1

不幸的是,@EJB註釋僅適用於本地(單JVM)注入。對於單獨的主機,您需要回退到普通的JNDI查找。

AFAIK有一些專有的非便攜式解決方案來執行遠程依賴注入,如WebLogic服務器(here),但我不會這麼做。

JNDI查找的作品,但過於複雜和相當難看:

  • 你需要知道服務器廠商並增加其客戶庫與您的應用程序的依賴關係,
  • 你污染與應用:
    • 神祕的供應商特定URI格式
    • 供應商特定的命名服務端口NUMER(通常默認爲1099,但誰確切知道...)
    • 供應商特定JNDI名稱模式

這裏託管在遠程JBoss 4.x的實例bean的實例查找:

Properties properties = new Properties(); 
properties.put(Context.INITIAL_CONTEXT_FACTORY, 
    "org.jnp.interfaces.NamingContextFactory"); 
properties.put(Context.URL_PKG_PREFIXES, 
    "org.jboss.naming:org.jnp.interfaces"); 
properties.setProperty(Context.PROVIDER_URL, "localhost:1099"); 
InitialContext context = null; 
ClientDataAccessRemote cl = null; 
try { 
    context = new InitialContext(properties); 
    cl = (ClientDataAccessRemote) context.lookup("ClientDataAccess/remote"); 
} catch (NamingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

鑑於你的EJB是你需要前綴EAR的一部分EJBean中的耳的名字命名:

cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote"); 

上面的例子是JBoss的具體,我甚至不知道是否會與JBoss 5.x的系列工作,而無需修改。

顯然,EJB 3.1規範帶來了一些統一到JNDI命名,但我還沒有得到快感尚未與它合作。

如果這個例子嚇你一點點,也許是更好的解決方案會暴露你的EJB作爲Web服務(SOAP或REST風格)。 它帶來了自己的問題,但至少是可移植的。

+0

如您所知,某些應用程序服務器支持使用@EJB註釋來定位遠程bean,包括JBoss(根據rodrigo的回答)和Glassfish。可移植性有時是一種有用的屬性,但這取決於情況。同樣,Web服務本身並不優於RMI:這取決於情況。 – DavidS 2015-09-30 22:24:41