web-dev-qa-db-ja.com

Java RMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()とextends UnicastRemoteObjectの違いは何ですか?

試験の準備をしていますが、ここの誰かが私に答えてくれることを願っています。

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番目のバージョンでは、レジストリはすでに作成されているようです。名前へのバインドがレジストリへの直接バインドと同じであるのはなぜですか?

これは、私が思うことです:

  • 最初のクラスのディレクトリは、インターフェイスUnicastRemoteObjectを実装します。これは、実行時にレジストリが作成され、オブジェクトがRMIレジストリに自動的にエクスポートされることを意味します。
  • オブジェクトはすでにレジストリにバインドされているため、通常のバインドではなく再バインドを実行する必要があります。
  • 後者はこれをすべて明示的に行います。
18

Java.rmi.server.UnicastRemoteObjectは、Java Remote Method Protocol(JRMP)を使用してリモートオブジェクトをエクスポートし、リモートオブジェクトと通信するスタブを取得するために使用されます。

以下のコンストラクターと静的exportObjectメソッドの場合、エクスポートされるリモートオブジェクトのスタブが取得されます...

そこで、 Javadoc に従う必要があります

4
stacker

ここには2つの質問があります。

  1. UnicastRemoteObjectを拡張するか、UnicastRemoteObject.exportObject().を呼び出すことができます。どちらを行うかはあなた次第です。 1つ目は、シンプルで自動です。 2つ目は、別のクラスを拡張できることを意味します。

  2. 外部RMIレジストリを使用するか、サーバーJVM内に自分で作成することができます。繰り返しますが、どちらを行うかはあなた次第ですが、どちらの方法にも利点があります。

    これらの2つの質問には相互作用がありません。

  3. _extend UnicastRemoteObject_の場合、hashCode()メソッドとequals()メソッドの「リモートセマンティクス」の利点も得られるため、すべてのスタブがエクスポートされたリモートオブジェクトと同一であるように見えます。ただし、これはクライアント側では実用的ではなく、実際にはRMI実装自体をサポートするためにのみ存在します。

19
user207421

まず、NamingクラスとRegistryクラスを使用したリモートオブジェクトのバインドと再バインドは、クラスがUnicastRemoteObjectを拡張しているかどうかのシナリオとは関係ありません。違いについては ここ を参照してください。

次に、UnicastRemoteObjectを拡張するクラスの違いは、そのタイプのオブジェクトがスタブとして使用されている場合、レジストリとのバインドのためにスタブを取得するためにUnicastRemoteObject.exportObjectを呼び出す必要がないことです。バージョン1では、StorehouseImplUnicastRemoteObjectを拡張している必要があります。実際、EchoImplのインスタンスがレジストリにリモートオブジェクトとして登録されていないため、UnicastRemoteObjectがバージョン1のEchoImplを拡張する必要はありません。

第三に、rebindを事前に実行せずにbindを実行するとどうなるかについて説明します。 javadoc here で説明されているように、キー名が挿入されていない場合は、最初にbindが実行されたときと同じように動作します。

0
atjua

他のクラスを拡張する必要があるシナリオでは、UnicastRemoteObjectを拡張する代わりに、UnicastRemoteObject.exportObject()を呼び出すことができます。全体的な効果は同じだと思います。

これを参照

0
A Gilani