A Чистое решение RMI : объект прослушивателя на стороне клиента должен реализовывать java.rmi.server.UnicastRemoteObject
.Если это так, и каждый из его методов выдает RemoteException
, то, когда он передается на сервер через прокси-сервер менеджера, все автоматически подключается, и вызовы методов на прокси-сервере на стороне этого слушателя являются удаленными вызовами методов на сервере.настоящий объект на стороне клиента.
Это подойдет, но еще лучше иметь возможность обернуть объект для экспорта, не требуя конкретного суперкласса .Мы можем использовать CGLIB Enhancer для «прокси» прослушивания в качестве подкласса UnicastRemoteObject
, который также реализует сервисные интерфейсы.Для этого все еще требуется, чтобы целевой объект реализовал java.rmi.Remote
и объявил throws RemoteException
.
Следующим шагом является решение , которое может экспортировать произвольные объекты для удаленного вызова их методов, не требуя, чтобы ониреализовать Remote
или объявить throws RemoteException
.Мы должны интегрировать этот прокси с существующей инфраструктурой Spring, что мы можем сделать с новой реализацией RmiBasedExporter
, смоделированной с нерегистрационными битами RmiServiceExporter#prepare()
, чтобы экспортировать заглушку RMI нашего прокси-сервера и часть вызова RmiClientInterceptor.doInvoke(MethodInvocation, RmiInvocationHandler)
.Нам нужно иметь возможность получить экспортированный экземпляр прокси-интерфейса наших сервисных интерфейсов.Мы можем смоделировать это с помощью средств, используемых Spring для «экспорта» интерфейсов без RMI.Spring проксирует интерфейс для генерации RmiInvocationWrapper
для вызова метода без RMI, сериализует детали метода и аргументы, а затем вызывает его на дальней стороне RMI-соединения.
- Use a
ProxyFactory
и реализация RmiInvocationHandler
для прокси целевого объекта. - Используйте новую реализацию от
RmiBasedExporter
до getObjectToExport()
и экспортируйте ее, используя UnicastRemoteObject#export(obj, 0)
. - Для вызоваобработчик,
rmiInvocationHandler.invoke(invocationFactory.createRemoteInvocation(invocation))
, с DefaultRemoteInvocationFactory
. - Обрабатывать исключения и переносить их соответствующим образом, чтобы не видеть
UndeclaredThrowableException
s.
Таким образом, мы можем использовать RMI для экспорта произвольных объектов,Это означает, что мы можем использовать один из этих объектов на стороне клиента в качестве параметра для вызова метода RMI для объекта на стороне сервера RMI, и когда десериализованная заглушка на стороне сервера вызывает методы, эти методы будут выполняться насторона клиента.Магия.