RMI是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。
首先我考虑在Spring环境下使用RMI,使用那是相当的简单,可是后来还是不得不放弃了Spring,因为要求服务端和客户端全都要有Spring环境,或许在没有Spring环境的客户端上可以实现,我研究了半天,无果。
不使用Spring的环境下,RMI的使用也颇费周折,下面还是直接上代码吧:
先来写服务器端代码:
接口example.Hello.java
public String say() throws RemoteException;
}
这个接口必须要继承Remote接口
实现类 example.HelloImpl
protected HelloImpl() throws RemoteException {
super ();
}
public String say() throws RemoteException {
return " hello world " ;
}
}
除了要实现Hello接口,还要继承UnicastRemoteObject类,这个也是必须的
接下来注册服务,打开RMI端口,提供服务
public static void main(String[] args) throws RemoteException,MalformedURLException {
LocateRegistry.createRegistry( 1099 );
Hello hello = new HelloImpl();
Naming.rebind( " rmi://192.168.0.80:1099/myservice " , hello);
System.out.println( " finish " );
// UnicastRemoteObject.unexportObject(sh, true);
}
}
很恶心的是,打开完RMI后,端口关不掉了,必须重启服务器。使用UnicastRemoteObject.unexportObject(sh, true) 可以,可是打开了就立即关掉,那这服务还有什么用呢。呼呼,或许把实例的hello类放到application里,或者通过其它方式,需要关闭端口的时候,再把这个实例的类找出来,或许可以,我也没有试,感兴趣的话,可以试一下。
现在服务端终于完了,接下来写客户端:
把服务端的接口example.Hello.java拷过来,跟服务器的包名类名都要一模一样,不然会出错,又是很恶心的地方:(
接下来写调用的代码:
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry( " 192.168.0.80 " , 1099 );
Hello hello = (Hello)registry.lookup( " myservice " );
System.out.println(jTest1.say());
} catch (Exception e) {
e.printStackTrace();
}
}
}
服务器端执行完注册服务的代码,开启RMI服务器,就可以执行客户端代码了。
最后我简单总结一下RMI
优点我就不说了,网上搜一下,有很多
缺点目前我知道的有:
1.服务端和客户端必须都是Java,无法与其它编程语言通信
2.必须开启额外的端口,有一定的局限性,客户那里不一定允许
我也没有深入的使用,不过感觉不是很灵活,真正需要使用的话,还是要三思一下。