深入Java分布式计算的使用分析
辅助设施的任务辅助设施是个在实际上执行通信的对象,他们会让客户端感觉上好像是在调用本机对象,客户端对象看起来像是在调用远程的方法,但实际上它只是在调用本地处理Socket和串流细节的代理.在服务器这端,服务器的辅助设施会通过socket连接来自客户端设施的要求,解析打包送来的信息,然后调用真正的服务,因此对服务对象来说此调用来自本地.服务的辅助设施取得返回值之后就把它包装然后送回去(通过socket的输出串流)给客户端的辅助设施.客户端的辅助设施会解开这些信息传输给客户端的对象
importjava.rmi.Remote;
importjava.rmi.RemoteException;
/**
*
* MyRemote.java
*
* 功 能:TODO
* 类 名:MyRemote.java
*
* ver ?涓??nbsp; 角色 担当者 ?涓?谌?BR> * ──────────────────────────────────────────────
* V1.00 2013-3-19 模块 苏若年 初版
*
* Copyright(c)2013dennisitcorporationAllRightsReserved.
*
* Email:<ahref="mailto:DennisIT@163.com">发送邮件</a>
*
*
* Remote是个标记性的接口,意味着没有方法,然而它对RMI有特殊的意义,所以必须遵守这项规则,
* 注意这里用的是extends,接口是可以继承其他接口的
*
*/
publicinterfaceMyRemoteextendsRemote{
/**
*远程的接口定义了客户端可以远程调用的方法,它是作为服务的多态化类,也就是说,客户端会
*调动有实现此接口的stub,而此stub因为会执行网络和输入/输出工作,所以可能会发生各种
*问题,客户端鼻息处理或声明异常来认知这一类风险,如果该方法在接口中声明异常,调用该方
*法的所有程序都必须处理或再声明此异常.
*
*远程方法的参数和返回值必须是primitive或serializable的.任何远程方法的参数都会被
*打包通过网络传送,而这时通过序列化完成的,返回值也是一样.所以,如果使用的是自定义类型
*时,必须对其序列化
*@return
*@throwsRemoteException
* 所有接口中的方法都必须声明RemoteException
*/
publicStringsayHello()throwsRemoteException;
}
业务实现
importjava.rmi.Naming;
importjava.rmi.RemoteException;
importjava.rmi.server.UnicastRemoteObject;
/**
*
* MyRemoteImpl.java
*
* 功 能:TODO
* 类 名:MyRemoteImpl.java
*
* ver ?涓??nbsp; 角色 担当者 ?涓?谌?BR> * ──────────────────────────────────────────────
* V1.00 2013-3-19 模块 苏若年 初版
*
* Copyright(c)2013dennisitcorporationAllRightsReserved.
*
* Email:<ahref="mailto:DennisIT@163.com">发送邮件</a>
*
* 为了要成为远程服务对象,对象必须要有与远程有关的功能,其中最简单的方法就是继承UnicastRemoteObject
* (来自java.rmi.server)以让这个父类处理这些工作
*
*/
publicclassMyRemoteImplextendsUnicastRemoteObjectimplementsMyRemote{
/**
*父类的构造函数声明了异常,所有你必须写出构造函数,因为它代表你的构造函数会调用有风险的程序代码
*
*UnicastRemoteObject有个小问题,它的构造函数会抛出RemoteException.处理它的唯一方式就是
*对自己的实现声明一个构造,如此才会有地方可以声明出RemoteException.当类被初始化的时候,父类
*的构造函数一定会被调用,如果父类的构造函数抛出异常,我们也必须声明的自定义的构造函数会抛出异常
*@throwsRemoteException
*/
protectedMyRemoteImpl()throwsRemoteException{
}
/**
*实现出接口所有的方法,但无需声明RemoteException
*/
@Override
publicStringsayHello(){
return"serversays,rmihelloworld!";
}
publicstaticvoidmain(String[]args){
try{
/**
*我们已经有了远程服务,还必须要让远程用户存取,这可以通过将它初始化并加进RMIRegistry
*(它一定要运行起来,不然此程序就会失败).当注册对象时,RMI系统会把stub加到registry中,
*因为这是客户端所需要的.使用java.rmi.Naming的rebind()来注册服务
*/
MyRemoteservice=newMyRemoteImpl();
/**
*创建出远程对象,然后使用静态的Naming.rebind()来产生关联,所注册的名称会提供客户端查询
*/
Naming.rebind("RemoteHelloWorld",service);
}catch(Exceptione){
e.printStackTrace();
}
}
}
客户端代码
importjava.rmi.Naming;
/**
*
* MyRemoteClient.java
*
* 功 能:TODO
* 类 名:MyRemoteClient.java
*
* ver ?涓??nbsp; 角色 担当者 ?涓?谌?BR> * ──────────────────────────────────────────────
* V1.00 2013-3-19 模块 苏若年 初版
*
* Copyright(c)2013dennisitcorporationAllRightsReserved.
*
* Email:<ahref="mailto:DennisIT@163.com">发送邮件</a>
*
*/
publicclassMyRemoteClient{
publicvoidexec(){
try{
/**
*客户端必须取得stub对象,因为客户端必须要调用它的方法.这就得靠RMIregistry了.客户端会像查询电话
*簿一样地搜索,找出上面有相符的名称的服务.
*客户端查询RMIRegistry,返回stub对象
*Naming.lookup("rmi://127.0.0.1/RemoteHelloWorld");
*参数说明
*rmi://127.0.0.1/RemoteHelloWorld
*127.0.0.1表示主机名称或主机IP地址
*RemoteHelloWorld必须要跟注册的名称一样
*
*/
MyRemoteservice=(MyRemote)Naming.lookup("rmi://127.0.0.1/RemoteHelloWorld");
Stringtmp=service.sayHello();
System.out.println(tmp);
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticvoidmain(String[]args){
newMyRemoteClient().exec();
}
}
对实现出的类(不是remote接口)执行rmic
伴随JDK而来的rmic工具会以服务的实现产生2个心的类stub和skeleton.它会按照命名规则在远程实现名称后面加上_Stub或_Skeleton。rmic有几个选项,包括了不产生skeleton、观察产生出类的源代码或使用IIOP作为通讯协议等.产生出的类会放在当前目录下,要记住rmic必须能够找到所实现的类,因此可能要从实现所在的目录执行rmic(实际中可能需要考虑到包目录结构和完整名称,为了简便这里没有运用到包)
调用命令行来启动rmiregistry,要确定是从可以存取到该类的目录来启动,最简单的方法就是从类这个目录来运行.
相关文章
- java scanner怎么用_Java中Scanner类的用法及使用步骤分享!「建议收藏」
- java源程序文件扩展名_JAVA源代码的扩展名为( )
- java ee简介_Java EE 简介
- java环境_Java基础篇——环境配置
- java生成license_使用truelicense实现用于JAVA工程license机制(包括license生成和验证)…
- java验证手机号正则表达式_Java使用正则表达式验证手机号和电话号码的方法「建议收藏」
- 大人,时代变了!使用 Java 16 或 Kotlin 更好的进行插件或模组开发
- java 数字信封_【Java密码学】使用Bouncy Castle生成数字签名、数字信封
- Java学习笔记(线程池简单的使用)
- Java 线程池(ThreadPoolExecutor)原理分析与使用详解编程语言
- Java NIO介绍和基本使用demo详解编程语言
- Java Date类的使用总结详解编程语言
- 数据库解锁Java,优雅连接Oracle数据库(java使用oracle)
- Oracle 视图 DBA_JAVA_RESOLVERS 官方解释,作用,如何使用详细说明
- 利用Redis存储Java对象的方法(redis存储java对象)
- java 线程池 spring线程池 多线程知识总结详解编程语言
- 使用Java实现Redis中Key的过期管理(redisjava过期)
- 策略Java使用Redis实现过期策略(redisjava过期)
- 使用Java实现MySQL数据恢复操作(java恢复mysql)
- Java解答Oracle使用更轻松的实现方式(oracle写成java)
- Java中Oracle使用实践(java中oracle题)
- 缓存使用Redis让Java代码更加迅速缓存设置(redis设置java)