Dependency injection 通过带有@EJB的远程接口访问企业bean
我有这样一个界面:Dependency injection 通过带有@EJB的远程接口访问企业bean,dependency-injection,ejb,javabeans,remote-access,Dependency Injection,Ejb,Javabeans,Remote Access,我有这样一个界面: @Remote public interface ClientDataAccessRemote EJB实现了它: @Stateless public class ClientDataAccess implements ClientDataAccessRemote 在远程客户端中,我可以通过以下方式访问EJB: @EJB private static ClientDataAccessRemote clientDataAccess; 这就是我所做的一切,而且很有效。客户机
@Remote
public interface ClientDataAccessRemote
EJB实现了它:
@Stateless
public class ClientDataAccess implements ClientDataAccessRemote
在远程客户端中,我可以通过以下方式访问EJB:
@EJB
private static ClientDataAccessRemote clientDataAccess;
这就是我所做的一切,而且很有效。客户机和EJB驻留在同一台服务器上。如果他们分开,还能用吗?容器如何找到具有该接口的EJB?我用Netbeans实现了这一点,我不需要指定任何位置或类似的东西。这是如何工作的?不幸的是@EJB注释仅适用于本地(单个JVM)注入。对于单独的主机,您需要回退到普通JNDI查找 AFAIK有一些专有的不可移植的解决方案来执行远程依赖注入,比如WebLogic server(),但我不会这样做 JNDI查找工作正常,但过于复杂且非常难看:
- 您需要了解服务器供应商,并将其客户端库添加到应用程序的依赖项中
- 您使用以下方法污染应用程序:
- 神秘的特定于供应商的URI格式
- 特定于供应商的命名服务端口号(通常默认为1099,但谁确切知道…)
- 特定于供应商的jndi名称模式
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的名称前面加上EAR的名称:
cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote");
上面的例子是JBoss特有的,我甚至不确定它是否可以在不做修改的情况下与JBoss5.x系列一起使用
显然EJB3.1规范为jndi命名带来了一些统一,但我还没有愉快地使用它
如果这个示例让您有点害怕,那么更好的解决方案可能是将EJB公开为web服务(SOAP或REST样式)。
它带来了自身的问题,但至少是可移植的。不幸的是@EJB注释只适用于本地(单个JVM)注入。对于单独的主机,您需要回退到普通JNDI查找 AFAIK有一些专有的不可移植的解决方案来执行远程依赖注入,比如WebLogic server(),但我不会这样做 JNDI查找工作正常,但过于复杂且非常难看:
- 您需要了解服务器供应商,并将其客户端库添加到应用程序的依赖项中
- 您使用以下方法污染应用程序:
- 神秘的特定于供应商的URI格式
- 特定于供应商的命名服务端口号(通常默认为1099,但谁确切知道…)
- 特定于供应商的jndi名称模式
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的名称前面加上EAR的名称:
cl = (ClientDataAccessRemote) context.lookup("MyEAR/ClientDataAccess/remote");
上面的例子是JBoss特有的,我甚至不确定它是否可以在不做修改的情况下与JBoss5.x系列一起使用
显然EJB3.1规范为jndi命名带来了一些统一,但我还没有愉快地使用它
如果这个示例让您有点害怕,那么更好的解决方案可能是将EJB公开为web服务(SOAP或REST样式)。
它带来了自身的问题,但至少是可移植的。正如您所承认的,一些应用服务器支持使用@EJB注释来定位远程bean,包括JBoss(根据rodrigo的回答)和Glassfish。可移植性有时是一个有用的属性,但这取决于具体情况。同样,web服务也并非天生优于RMI:这取决于具体情况。正如您所承认的,一些应用服务器支持使用@EJB注释来定位远程bean,包括JBoss(根据rodrigo的回答)和Glassfish。可移植性有时是一个有用的属性,但这取决于具体情况。同样,web服务也并非天生优于RMI:这取决于具体情况。