RMI-Server: rmiregistry oder LocateRegistry.createRegistry
-
01-07-2019 - |
Frage
Für RMI auf serverseitige, brauchen wir rmiregistry
Programm zu starten, oder einfach nur LocateRegistry.createRegistry
nennen?
Wenn beide möglich sind, was sind die Vor- und Nachteile?
Lösung
Sie sind das gleiche ... rmiregistry
ein eigenes Programm, das Sie von einer Befehlszeile oder einem Skript ausführen können, während LocateRegistry.createRegistry
die gleiche Sache programmatisch der Fall ist.
Nach meiner Erfahrung für „echte“ Server wollen Sie rmiregistry
verwenden, so dass Sie wissen, dass es immer läuft, unabhängig davon, ob die Client-Anwendung gestartet wird. createRegistry
ist sehr nützlich für die Prüfung, wie Sie können die Registrierung von Ihrem Test nach Bedarf starten und stoppen.
Andere Tipps
Wenn wir beginnen rmiregistry ersten, würde RmiServiceExporter selbst rmiregistry zur Lauf registrieren. In diesem Fall haben wir die Systemeigenschaft ‚java.rmi.server.codebase‘ gesetzt werden, wo die Klasse ‚org.springframework.remoting.rmi.RmiInvocationWrapper_Stub‘ gefunden werden kann. Andernfalls würde die RmiServiceExporter nicht gestartet werden, und bekam die Ausnahme " org.springframework.remoting.rmi.RmiInvocationWrapper_Stub;: ClassNotFoundException Klasse nicht gefunden verschachtelte Ausnahme ist: ... "
Wenn Ihr rmi Server, rmi Client und rmiregistry das gleiche Dateisystem zugreifen können, können Sie die Systemeigenschaft wollen automatisch konfiguriert werden, wo die spring.jar können auf dem gemeinsam genutzten Dateisystem gefunden werden. Die folgenden Utility-Klassen und Federkonfiguration zeigen, wie dies erreicht werden kann.
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>
Das obige Beispiel zeigt, wie Systemeigenschaft nur dann automatisch eingestellt werden, wenn rmi Server, rmi Client und RMI-Registry das gleiche Dateisystem zugreifen können. Wenn das nicht wahr oder Feder Code-Basis ist, über andere Methode (z HTTP) geteilt wird, können Sie die CodeBaseResolver ändern Ihre Notwendigkeit zu passen.
Wenn Sie eine eigenständige Java-Anwendung schreiben würden Sie wollen Ihr eigenes rmiregistry starten, aber wenn Sie schreiben, eine J2EE-Anwendung, die offensichtlich in einem J2EE-Container läuft dann Sie „LocateRegistry“ wollen, da es ohnehin schon ist man auf der App läuft Server!
Wenn Sie Frühling verwenden Ihre RMI Dienste zu exportieren, startet er automatisch eine Registrierung, wenn man nicht bereits ausgeführt wird. Siehe RmiServiceExporter