Java RMI - UnicastRemoteObject: в чем разница между UnicastRemoteObject.exportObject () и расширяет UnicastRemoteObject? - PullRequest
18 голосов
/ 03 февраля 2010

Я готовлюсь к экзамену, и у меня есть вопрос, который, я надеюсь, кто-то здесь может мне ответить.

Речь идет об RMI и удаленных объектах. Интересно, почему между этими двумя реализациями так много различий? один расширяет UnicastRemoteObject, тогда как другой экспортирует объект как 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);
        ...
    }
}

Мой вопрос: в чем разница между этими двумя?

В первой версии реестр создается в явном виде, кроме того, удаленный объект создается при повторном связывании?

Мне действительно любопытно, почему сначала мне нужно создать реестр самостоятельно, но не нужно явно экспортировать объект и просто привязать его заново, используя Naming. Этот объект уже связан с реестром ранее, или я мог бы вместо этого использовать связывание? И что произойдет, если объект ранее не был связан, и повторное связывание выполнено?

Во второй версии реестр, похоже, уже создан. Почему привязка к именованию совпадает с привязкой к реестру напрямую?

Это то, что я думаю:

  • первый класс direclty реализует интерфейс UnicastRemoteObject, который означает, что во время выполнения создается реестр, и объект автоматически экспортируется в реестр RMI.
  • , поскольку объект уже привязан к реестру, вместо обычной привязки должна быть выполнена повторная привязка.
  • последний делает все это явно.

Ответы [ 4 ]

19 голосов
/ 15 февраля 2010

Здесь есть два вопроса.

  1. Вы можете либо набрать UnicastRemoteObject, либо позвонить UnicastRemoteObject.exportObject(). Что вы делаете, решать только вам. Первый простой и автоматический; второе означает, что вы можете расширить другой класс.

  2. Вы можете использовать внешний реестр RMI или создать его самостоятельно в JVM вашего сервера. Опять же, что вы делаете, зависит от вас, есть преимущества в обоих направлениях.

    Эти два вопроса не имеют взаимодействия.

  3. Если вы extend UnicastRemoteObject, вы также получите преимущество «удаленной семантики» для методов hashCode() и equals(), так что все заглушки будут идентичны удаленному объекту, который их экспортировал, но не имеет практического применения на стороне клиента, и действительно только для поддержки самой реализации RMI.

4 голосов
/ 04 февраля 2010

java.rmi.server.UnicastRemoteObject используется для экспорта удаленного объекта по протоколу Java Remote Method Protocol (JRMP) и получения заглушки, которая связывается с удаленным объектом

Для конструкторов и статических exportObject методов ниже получена заглушка для экспортируемого удаленного объекта ...

Там вы должны следовать Javadoc

0 голосов
/ 22 декабря 2016

Во-первых, привязка и повторное связывание удаленного объекта с использованием класса Naming и класса Registry не имеет отношения к сценариям того, расширяет ли класс UnicastRemoteObject. См. здесь для различий.

Во-вторых, различие между классом, расширяющим UnicastRemoteObject, состоит в том, что если объект этого типа используется в качестве заглушки, вам не нужно будет вызывать UnicastRemoteObject.exportObject, чтобы больше получать заглушку для связывания с реестром. В вашей версии 1 StorehouseImpl должен был расширить UnicastRemoteObject, и на самом деле, EchoImpl не нужно расширять UnicastRemoteObject для вашей версии 1, так как нет экземпляра EchoImpl, зарегистрированного как удаленный объект в реестре.

В-третьих, вы упоминаете, что произойдет, если rebind будет выполнен без bind, выполненным заранее. Как объясняется в javadoc здесь , если имя ключа не было вставлено, оно будет вести себя так же, как если бы в первый раз bind был выполнен.

0 голосов
/ 26 ноября 2013

Вы можете вызвать UnicastRemoteObject.exportObject() вместо расширения UnicastRemoteObject в сценарии, где вам нужно расширить любой другой класс.Общий эффект тот же, я думаю.

Смотрите это

...