前段时间学习JMX,知道可以使用rmi连接器,就顺便看下rmi是什么东西,RMI 全称Remote Method Invocation-远程方法调用,实现远程对象之间的调用,下面原理图来自网络
服务器端定义接口和实现
public interface FFMMendService extends Remote { Long doReSend(long rcvId) throws RemoteException; } public class FFMMendServiceImpl extends UnicastRemoteObject implements FFMMendService {
//必须实现一个现实构造函数,并抛出RemoteException protected FFMMendServiceImpl() throws RemoteException { } }
继承自UnicastRemoteObject,客户端执行的是远程对象,否则,客户端是反序列化出的新对象,方法调用就与远程对象无关了
发布下
private static void publicRmi(Remote remote,int port) throws RemoteException, MalformedURLException { LocateRegistry.createRegistry(port); Naming.rebind(rmiUrl, remote); //rmiUrl=rmi://127.0.0.1:9797/robotservice
}
实例化FFMMendServiceImpl,发布在rmi://127.0.0.1:9797/robotservice地址上
完了,so easy。。
客户端使用
FFMMendService remote = (FFMMendService)Naming.lookup("rmi://127.0.0.1:9797/robotservice");
就可以向本地对象一样调用 FFMMendServiceImpl了
如果和spring结合
服务器端配置
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"> <property name="port" value="1099"/> </bean> <bean id="rmiServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter"> <!– 调用Service –> <property name="service" ref="ffmMendService" /> <!– value值是提供给客户端调用 –> <property name="serviceName" value="robotservice" /> <!– service接口 –> <property name="serviceInterface" value="mf.ffm.receiver.service.FFMMendService" /> <!– 注册端口 –> <!--<property name="registryPort" value="9797" />--> <property name="registry" ref="registry"/> </bean>
还可配置servicePort,此属性默认是0,由系统选择,是rmi服务的数据端口
客户端配置
<bean id="rmiService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> <property name="serviceUrl" value="rmi://127.0.0.1:9797/robotservice" /> <!– service接口 –> <property name="serviceInterface" value="mf.ffm.receiver.service.FFMMendService" /> <property name="refreshStubOnConnectFailure" value="true"></property> <property name="lookupStubOnStartup" value="false"></property> </bean>
rmiService就是远程对象的一个代理了
注:客户端在使用时要有服务器端的相关接口定义,例如 interface FFMMendService
参考文章:
1. RMI 相关知识