2013-02-23 53 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