Java RMI服务器:rmiregistry或LocateRegistry.createRegistry

Java RMI服务器:rmiregistry或LocateRegistry.createRegistry,java,rmi,rmiregistry,Java,Rmi,Rmiregistry,对于服务器端的RMI,我们需要启动rmiregistry程序,还是只需调用LocateRegistry.createRegistry? 如果两者都有可能,那么优点和缺点是什么?它们是一样的rmiregistry是一个单独的程序,您可以从命令行或脚本运行,而LocateRegistry.createRegistry通过编程执行相同的操作 根据我的经验,对于“真正”的服务器,您将希望使用rmiregistry,这样您就知道无论客户端应用程序是否启动,它总是在运行createRegistry对于测试非

对于服务器端的RMI,我们需要启动
rmiregistry
程序,还是只需调用
LocateRegistry.createRegistry

如果两者都有可能,那么优点和缺点是什么?

它们是一样的
rmiregistry
是一个单独的程序,您可以从命令行或脚本运行,而
LocateRegistry.createRegistry
通过编程执行相同的操作


根据我的经验,对于“真正”的服务器,您将希望使用
rmiregistry
,这样您就知道无论客户端应用程序是否启动,它总是在运行
createRegistry
对于测试非常有用,因为您可以根据需要从测试中启动和停止注册表。

如果您正在编写独立的java应用程序,您可能希望启动自己的RMIRRegistry,但是如果您正在编写一个显然在J2EE容器中运行的J2EE应用程序,那么您需要“定位注册表”因为应用服务器上已经有一个在运行

如果您使用Spring导出RMI服务,如果注册表尚未运行,它会自动启动注册表。请参见

如果我们首先启动rmiregistry,RmiServiceExporter将自己注册到正在运行的rmiregistry。在这种情况下,我们必须将系统属性“java.rmi.server.codebase”设置为可以找到“org.springframework.remoting.rmi.rmi”Stub类的位置。否则,RmiServiceExporter将无法启动并获得异常“ 找不到ClassNotFoundException类:org.springframework.remoting.rmi.RmiInvocationWrapper_存根;嵌套异常为:…”

如果您的rmi服务器、rmi客户端和rmi注册表可以访问同一个文件系统,那么您可能希望将系统属性自动配置为共享文件系统上可以找到spring.jar的位置。下面的实用程序类和spring配置说明了如何实现这一点

abstract public class CodeBaseResolver { 
  static public String resolveCodeBaseForClass(Class<?> clazz) {
    Assert.notNull(clazz);
    final CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
    if (codeSource != null) {
      return codeSource.getLocation().toString();
    } else {
      return "";
    }
  }
}

public class SystemPropertyConfigurer {
  private Map<String, String> systemProperties;
  public void setSystemProperties(Map<String, String> systemProperties) {
    this.systemProperties = systemProperties;
  }

  @PostConstruct
  void init() throws BeansException {
    if (systemProperties == null || systemProperties.isEmpty()) {
      return;
    }
    for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
      final String key = entry.getKey();
      final String value = SystemPropertyUtils.resolvePlaceholders(entry.getValue());
      System.setProperty(key, value);
    }
  }
}


<bean id="springCodeBase" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="staticMethod" value="xx.CodeBaseResolver.resolveCodeBaseForClass" />
  <property name="arguments">
    <list>
      <value>org.springframework.remoting.rmi.RmiInvocationWrapper_Stub</value>
    </list>
  </property>
</bean>

<bean id="springCodeBaseConfigurer" class="xx.SystemPropertyConfigurer"
  depends-on="springCodeBase">
  <property name="systemProperties">
    <map>
      <entry key="java.rmi.server.codebase" value-ref="springCodeBase" />
    </map>
  </property>
</bean>

<bean id="rmiServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter" depends-on="springCodeBaseConfigurer">
  <property name="serviceName" value="XXX" />
  <property name="service" ref="XXX" />
  <property name="serviceInterface" value="XXX" />
  <property name="registryPort" value="${remote.rmi.port}" />
</bean>
抽象公共类CodeBaseResolver{
静态公共字符串resolveCodeBaseForClass(clazz类){
Assert.notNull(clazz);
final CodeSource CodeSource=clazz.getProtectionDomain().getCodeSource();
if(codeSource!=null){
返回codeSource.getLocation().toString();
}否则{
返回“”;
}
}
}
公共类SystemPropertyConfiguration{
私有地图系统属性;
公共void集合系统属性(映射系统属性){
this.systemProperties=systemProperties;
}
@施工后
void init()抛出BeansException{
if(systemProperties==null | | systemProperties.isEmpty()){
返回;
}
对于(Map.Entry:systemProperties.entrySet()){
最后一个字符串key=entry.getKey();
最终字符串值=SystemPropertyUtils.resolvePlaceholders(entry.getValue());
System.setProperty(键、值);
}
}
}
org.springframework.remoting.rmi.rmi\u存根

上面的示例显示了只有当rmi服务器、rmi客户端和rmi注册表可以访问同一文件系统时,如何自动设置系统属性。如果不是这样,或者spring codebase通过其他方法(例如HTTP)共享,则可以修改CodeBaseResolver以满足您的需要

您可以编辑此文件以包含指向此功能文档的链接吗?createRegistry是否有一种方法可以在“localhost”之外的接口上工作?更新:文档中说“createRegistry”在localhost上导出注册表。但是,注册表也可以接受来自外向接口的连接。@Eagle导出在本地主机中运行的注册表。这并不意味着它只是在听127.0.0.1。不真实和没有动机。您可能也希望在独立程序中使用LocateRegistry。