試験の準備をしていますが、ここの誰かが私に答えてくれることを願っています。
RMIとリモートオブジェクトについてです。これら2つの実装の間になぜそれほど大きな違いがあるのだろうか。 1つはUnicastRemoteObjectを拡張し、もう1つはオブジェクトをUnicastRemoteObjectとしてエクスポートします。
違いはわかりません
インターフェース:
public interface EchoI extends Remote {
public String echo() throws RemoteException
}
これはサーバーコード(バージョン1)です:
public class EchoImpl extends UnicastRemoteObject implements EchoI {
public EchoImpl {
super();
}
public static void main (String[] args) {
try {
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
StoreHouse storehouseImpl = new StorehouseImpl();
Naming.rebind("//localhost/StoreHouse.SERVICE_NAME", storehouseImpl);
System.out.println("Server ready");
} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public String echo() {
return "echo";
}
}
これはバージョン2になります。
public class EchoImpl implements EchoI {
public static void main (String[] args) {
EchoI echoService = new EchoImpl();
EchoI stub = (EchoI) UnicastRemoteObject.exportObject(echoService, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("echoService", stub);
...
}
}
私の質問は:これら2つの違いは何ですか?
最初のバージョンでは、レジストリが明示的に作成され、さらにリモートオブジェクトが再バインド内で作成されますか?
私は本当に興味があります。最初に自分でレジストリを作成する必要があるのに、オブジェクトを明示的にエクスポートする必要がなく、Naming
を使用して再バインドする必要があるのはなぜですか。そのオブジェクトは以前にレジストリにバインドされていますか、それとも代わりにバインドを使用できますか?また、オブジェクトが以前にバインドされておらず、再バインドが実行された場合はどうなりますか?
2番目のバージョンでは、レジストリはすでに作成されているようです。名前へのバインドがレジストリへの直接バインドと同じであるのはなぜですか?
これは、私が思うことです:
Java.rmi.server.UnicastRemoteObject
は、Java Remote Method Protocol(JRMP)を使用してリモートオブジェクトをエクスポートし、リモートオブジェクトと通信するスタブを取得するために使用されます。
以下のコンストラクターと静的exportObject
メソッドの場合、エクスポートされるリモートオブジェクトのスタブが取得されます...
そこで、 Javadoc に従う必要があります
ここには2つの質問があります。
UnicastRemoteObject
を拡張するか、UnicastRemoteObject.exportObject().
を呼び出すことができます。どちらを行うかはあなた次第です。 1つ目は、シンプルで自動です。 2つ目は、別のクラスを拡張できることを意味します。
外部RMIレジストリを使用するか、サーバーJVM内に自分で作成することができます。繰り返しますが、どちらを行うかはあなた次第ですが、どちらの方法にも利点があります。
これらの2つの質問には相互作用がありません。
_extend UnicastRemoteObject
_の場合、hashCode()
メソッドとequals()
メソッドの「リモートセマンティクス」の利点も得られるため、すべてのスタブがエクスポートされたリモートオブジェクトと同一であるように見えます。ただし、これはクライアント側では実用的ではなく、実際にはRMI実装自体をサポートするためにのみ存在します。
まず、Naming
クラスとRegistry
クラスを使用したリモートオブジェクトのバインドと再バインドは、クラスがUnicastRemoteObject
を拡張しているかどうかのシナリオとは関係ありません。違いについては ここ を参照してください。
次に、UnicastRemoteObject
を拡張するクラスの違いは、そのタイプのオブジェクトがスタブとして使用されている場合、レジストリとのバインドのためにスタブを取得するためにUnicastRemoteObject.exportObject
を呼び出す必要がないことです。バージョン1では、StorehouseImpl
がUnicastRemoteObject
を拡張している必要があります。実際、EchoImpl
のインスタンスがレジストリにリモートオブジェクトとして登録されていないため、UnicastRemoteObject
がバージョン1のEchoImpl
を拡張する必要はありません。
第三に、rebind
を事前に実行せずにbind
を実行するとどうなるかについて説明します。 javadoc here で説明されているように、キー名が挿入されていない場合は、最初にbind
が実行されたときと同じように動作します。
他のクラスを拡張する必要があるシナリオでは、UnicastRemoteObject
を拡張する代わりに、UnicastRemoteObject.exportObject()
を呼び出すことができます。全体的な効果は同じだと思います。