发表于: 2020-08-13 23:21:18
1 1356
今天完成的事情:Spring RMI的总结学习。
明天计划的事情:将部署两台Service,部署两个Tomcat,负载均衡。
遇到的问题:暂无
收获:
Spring RMI和RMI
1.RMI
1.1介绍
RMI指的是远程方法调用 (Remote Method Invocation),远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制,使用这种机制,某一台计算机上的对象在调用另外一台计算机上的方法时,使用的程序语法规则和在本地机上对象间的方法调用的语法规则一样。
它强大的开发分布式网络应用的能力上,是纯 Java 的网络分布式应用系统的核心解决方案之一。其实它可以被看作是 RPC 的 Java 版本。但是传统 RPC 并不能很好地应用于分布式对象系统。而 Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
RMI 目前使用 Java 远程消息交换协议 JRMP(Java Remote Messaging Protocol)进行通信。由于 JRMP 是专为 Java 对象制定的,Java RMI 具有 Java 的 "Write Once,Run Anywhere" 的优点,是分布式应用系统的百分之百纯 Java 解决方案。用 Java RMI 开发的应用系统可以部署在任何支持 JRE 的平台上。但由于 JRMP 是专为 Java 对象制定的,因此,RMI 对于用非 Java 语言开发的应用系统的支持不足。不能与用非 Java 语言书写的对象进行通信。
RMI是java1.1开始的API功能,java原生的java.rmi包中的提供的,使用必须有一连串的繁杂的手续,像是服务介面定义时必须继承java.rmi.Remote,服务Server运作时必须继承java.rmi.UnicastRemoteObject类,必须使用rmic指令产生stub与skeleton等,设定上手续繁杂。
1.2 RMI 的组成
一个正常工作的 RMI 系统由下面几个部分组成:
a. 远程服务的接口定义
b. 远程服务接口的具体实现
c. 桩(Stub)和框架(Skeleton)文件
d. 一个运行远程服务的服务器
e. 一个 RMI 命名服务,它允许客户端去发现这个远程服务
f. 类文件的提供者(一个 HTTP 或者 FTP 服务器)
g. 一个需要这个远程服务的客户端程序
调用远程 RMI 的步骤:
a.客户调用客户端辅助对象 stub 上的方法
b.客户端辅助对象 stub 打包调用信息(变量,方法名),通过网络发送给服务端辅助对象 skeleton
c.服务端辅助对象 skeleton 将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
d.调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象 skeleton
e.服务端辅助对象将结果打包,发送给客户端辅助对象 stub
f.客户端辅助对象将返回值解包,返回给调用者
g.客户获得返回值
1.3 优点
a、面向对象:RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。像Java哈希表这样的复杂类型也作为一个参数进行传递。
b、可移动属性:RMI可将属性从客户机移动到服务器,或者从服务器移动到客户机。
c、分布式垃圾收集: RMI 采用其分布式垃圾收集功能收集不再被网络中任何客户程序所引用的远程服务对象。并行计算:RMI 采用多线程处理方法,可使您的服务器利用这些 Java 线程更好地并行处理客户端的请求。
d、安全性:RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。
e、便于编写和使用:远程接口实际上就是Java接口。
为了实现RMI的功能必须创建远程对象实现远程接口。但远程接口本身并不包含任何方法。因而需要创建一个新的接口来扩展远程接口。新接口将包含所有可以远程调用的方法。远程对象必须实现这个新接口,由于新的接口扩展了远程接口,实现了新接口,就满足了远程对象对实现远程接口的要求,所实现的每个对象都为远程对象引用。
2.Spring RMI
但是Spring RMI通过org.springframework.remoting.rmi.RmiServiceExporter来简化使用RMI的手续。
代码实现的小Demo,演示远程调用过程
2.1 服务端
Spring配置文件applicationContex.xml
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd"
default-autowire="byName" default-lazy-init="true">
<bean id="rmiserver" class="rmi.ServerRmiImpl"></bean>
<bean id="serverTest" class="org.springframework.remoting.rmi.RmiServiceExporter">
<!--service提供的服务-->
<property name="service" ref="rmiserver"/>
<!--serviceName对外提供服务的名称-->
<property name="serviceName" value="serverRmiTest"/>
<property name="serviceInterface" value="rmi.ServerRmiI"/><!--registryPort 注册端口端口 还有一个对应的服务端口,servicePort-->
<property name="registryPort" value="1021"/>
</bean>
</beans>
ServerRmiI接口
public interface ServerRmiI {
public String sayHi(String name);
}
ServerRmiImpl实现类
public class ServerRmiImpl implements ServerRmiI{
@Override
public String sayHi(String name) {
return "Hi," + name;
}
}
配置主方法,运行该服务
public class Testrun {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
context.getBean("serverTest");
}
}
2.2 客户端
spring配置applicationContext.xml
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
default-autowire="byName" default-lazy-init="true">
<bean id="clientrmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<!--服务端的地址-->
<property name="serviceUrl" value="rmi://127.0.0.1:1021/serverRmiTest"/>
<!--客户端的接口-->
<property name="serviceInterface" value="client.ServerRmiI"/>
</bean>
</beans>
ServerRmiI接口
public interface ServerRmiI {
public String sayHi(String name);
}
TestRun调用测试
public class TestRun {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ServerRmiI rmiI = (ServerRmiI) context.getBean("clientrmi");
System.out.println(rmiI.sayHi("你是最亮的星!"));
}
运行结果,Hi,字符段是服务端提供的方法内容。
评论