對於服務器端的RMI,我們需要啓動rmiregistry
程序,還是隻需撥打LocateRegistry.createRegistry
? 如果兩者都可能,有什麼優點和缺點?RMI服務器:rmiregistry或LocateRegistry.createRegistry
回答
它們是一樣的東西...... rmiregistry
是一個單獨的程序,您可以從命令行或腳本運行,而LocateRegistry.createRegistry
以編程方式執行相同的操作。
根據我的經驗,對於「真實」服務器,您將希望使用rmiregistry
,以便無論客戶端應用程序是否啓動,您都知道它始終在運行。 createRegistry
對測試非常有用,因爲您可以根據需要從註冊表中啓動和停止註冊表。
如果你正在編寫一個獨立的java應用程序,你會想開始你自己的rmiregistry,但是如果你正在編寫一個顯然運行在J2EE容器內的J2EE應用程序,那麼你想要「LocateRegistry」,因爲已經有一個運行在應用服務器!
如果您使用Spring導出您的RMI服務,它會自動啓動註冊表(如果尚未運行)。請參見RmiServiceExporter
如果我們先啓動rmiregistry,則RmiServiceExporter將自己註冊到正在運行的rmiregistry。在這種情況下,我們必須將系統屬性'java.rmi.server.codebase'設置爲可以找到'org.springframework.remoting.rmi.RmiInvocationWrapper_Stub'類的位置。否則,RmiServiceExporter不會被啓動,得到了異常「 ClassNotFoundException的類未找到:org.springframework.remoting.rmi.RmiInvocationWrapper_Stub;嵌套的例外是:......」
如果RMI服務器,RMI客戶端和rmiregistry的可以訪問相同的文件系統,您可能希望將系統屬性自動配置爲可在共享文件系統上找到spring.jar的位置。以下實用程序類和彈簧配置顯示瞭如何實現這一點。
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>
上面的例子說明了如何系統屬性被自動設置僅當RMI服務器,RMI客戶機和RMI註冊表可以訪問相同的文件系統。如果不是這樣,或者Spring代碼庫通過其他方法(例如HTTP)共享,那麼您可以修改CodeBaseResolver以適應您的需要。
- 1. 如何使用正確的參數運行rmiregistry和rmi服務器?
- 2. 獨立rmiregistry中和服務器應用
- 3. Java RMI InitialContext:等效於LocateRegistry.createRegistry(int)?
- 4. RMI服務器異常
- 5. 停止RMI服務器(JAVA)
- 6. RMI服務器停止?
- 7. 關閉Java RMI服務器
- 8. Java RMI服務器問題
- 9. Java RMI:同一臺機器上的多個rmiregistry
- 10. LocateRegistry.createRegistry
- 11. Docker容器中的Java RMI服務器
- 12. 測試RMI服務
- 13. Java(RMI)服務器到服務器的身份驗證方法?
- 14. Java RMI +源服務器來自互聯網或內部網
- 15. RMI:線程在等待服務器端
- 16. 使用Jolokia代理與RMI服務器
- 17. Jboss服務器中的RMI部署
- 18. java rmi服務器端異常處理
- 19. 在JBoss中公開RMI服務器?
- 20. 無法啓動RMI服務器它
- 21. Java RMI無法綁定服務器
- 22. RMI客戶端和服務器程序
- 23. 學生GUI與RMI服務器
- 24. 使用RMI檢測服務器崩潰
- 25. 運行RMI服務器的問題
- 26. 的Java RMI - 使客戶端服務器
- 27. Java RMI服務器端線程
- 28. java RMI連接到服務器
- 29. 乾淨地關閉rmi服務器
- 30. 連接到Websphere rmi服務器
有沒有辦法讓createRegistry在除「localhost」之外的界面上工作? – Eagle 2013-05-02 21:16:16
更新:文檔說''createRegistry''在Localhost上導出註冊表。但是,註冊表也能夠接受來自外向接口的連接。 – Eagle 2013-05-06 14:39:22
@Eagle導出在本地主機上運行的Registry *。沒有暗示它只能聽127.0.0.1。 – EJP 2017-07-05 03:28:45