如何在Spring框架中使用RMI技术
在博客《RMI远程方法调用技术》中使用纯Java代码演示了RMI技术的使用,本篇博客将介绍如何在Spring框架中使用RMI技术。
正如博客《RMI远程方法调用技术》提到的那样——RMI技术的应用通常包括在两个独立的应用程序中:RMI服务端应用程序和RMI客户端应用程序。本博客也从这两方面入手:
RMI服务端应用程序:
1、自定义远程接口
代码如下:
package com.ghj.packageofrmi;/*** 定义远程接口。* * @author 高焕杰*/
public interface IHelloWordService{/*** 获取信息* * @author 高焕杰*/String getMsg();
}
该自定义远程接口声明每个要远程调用的抽象方法。
该接口特点:
a、该接口没有继承java.rmi.Remote接口;
b、该接口中的每个抽象方法没有抛出RemoteException异常或RemoteException 的父类异常;
一句话,该接口和普通Java接口没什么区别,这与博客《 RMI远程方法调用技术》中的自定义远程接口有质的区别。
2、自定义远程接口实现类
代码如下:
package com.ghj.packageofrmi;/*** 远程接口实现类。* * @author 高焕杰*/
public class HelloWordService implements IHelloWordService{/*** 获取信息* * @author 高焕杰*/public String getMsg(){return "Hello World!"; }
}
该实现类特点:
a、该实现类必须实现自定义远程接口内的每个远程抽象方法;
b、该实现类没有继承java.rmi.UnicastRemoteObject类,这与博客《 RMI远程方法调用技术》中的自定义远程接口实现类不同的地方;
c、该实现类中默认的构造方法没有显示地写出来,该默认构造方法更没有声明抛出RemoteException异常,这与博客《 RMI远程方法调用技术》中的自定义远程接口实现类不同的地方;
d、该实现类也可以含有其它非远程接口定义的抽象方法或非接口方法(即实现类内部自定义的方法,这些方法不能使用@Override进行注释),但客户端不能调用这些新增的方法(别忘了,这些方法并不是自定义远程接口内的抽象方法)。
一句话,该实现类是普通Java实现类没有区别。
3、在xml文件中配置RMI服务端
代码如下:
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><!-- RMI服务端 --><!-- RMI服务端远程接口实现类 --> <bean id="helloWordService" class="com.ghj.packageofrmi.HelloWordService" scope="prototype"/><bean class="org.springframework.remoting.rmi.RmiServiceExporter"><!-- 将远程接口实现类对象设置到RMI服务中 --><property name="service" ref="helloWordService" /><!-- 设置RMI服务名,为RMI客户端依据此服务名获取远程接口实现类对象引用奠定基础 --><property name="serviceName" value="helloWord" /><!-- 将远程接口设置为RMI服务接口 --><property name="serviceInterface" value="com.ghj.packageofrmi.IHelloWordService" /><!-- 为RMI服务端远程对象注册表设置端口号--><property name="registryPort" value="9090" /><!-- 其他属性可以查看org.springframework.remoting.rmi.RmiServiceExporter的类及其子类获取到--></bean></beans>
该xml文件的配置就相当于博客《 RMI远程方法调用技术》中服务端RMI启动类内被try-catch包裹的那段Java代码。
4、启动RMI服务端
代码如下:
package com.ghj.packageoftest;import org.springframework.context.support.ClassPathXmlApplicationContext;/*** 启动RMI服务端* * @author 高焕杰*/
public class StartRMIServer {public static void main(String[] args) {new ClassPathXmlApplicationContext("conf/spring/applicationContext.xml");System.out.println("RMI服务端启动!!!");}
}
将RMI服务端配置到Spring框架内后,启动它是很简单的——只需Java加载配置文件上下文,在Spring容器生成相应的bean即可。
RMI客户端应用程序:
1、自定义包含了RMI服务端自定义远程接口内某些抽象方法的RMI客户端接口
代码如下:
package com.ghj.packageofrmi;/*** 自定义包含了RMI服务端自定义远程接口内某些抽象方法的RMI客户端接口* * @author 高焕杰*/
public interface IHelloWord{/*** 获取信息* * @author 高焕杰*/String getMsg();
}
该接口特点:
a、该接口的接口名无需和RMI服务端自定义远程接口名称相同;
b、该接口无须继承java.rmi.Remote接口;
c、该接口中需要通过RMI服务端远程对象调用的接口抽象方法需要和RMI服务端一样(这里的“一样”是指接口名、方法名和参数列表一样,注意:这里没有提及方法返回值类型,实验证明,返回值类型可以相同也可以是RMI服务端自定义远程接口相应抽象方法返回值类型的父类,例如该接口中的返回值类型完全可以改为Object,这一点与博客《 RMI远程方法调用技术》中的要求不一样——它要求返回值类型必须一致);
d、该接口中的抽象方法无须抛出RemoteException异常;
e、该接口可以包含RMI服务端自定义远程接口内不存在的抽象方法;
f、该接口无须包含RMI服务端自定义远程接口的所有抽象方法;
g、该接口完全可以直接复制RMI服务端自定义远程接口,但从代码精简的角度讲还是只保留需要的抽象接口为好。
2、在xml文件中配置RMI服务端
代码如下:
<?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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"><!--RMI客户端--><bean id="rmiProxyFactory" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> <property name="serviceUrl" value="rmi://localhost:9090/helloWord"/><property name="serviceInterface" value="com.ghj.packageofrmi.IHelloWord"/><!-- 当连接失败时是否刷新远程调用stub --><property name="refreshStubOnConnectFailure" value="true"/></bean>
</beans>
该xml文件的配置就相当于博客《 RMI远程方法调用技术》中客户端RMI调用远程方法测试类内被try-catch包裹的那段Java代码。
3、启动RMI客户端
代码如下:
package com.ghj.packageoftest;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.ghj.packageofrmi.IHelloWord;/*** 启动RMI客户端* * @author 高焕杰*/
public class RMIClient {public static void main(String[] args){ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/spring/applicationContext.xml");IHelloWord helloWord = (IHelloWord) ctx.getBean("rmiProxyFactory");System.out.println(helloWord.getMsg());}
}
从该Java类中可以看出来远程对象地址是通过RMI代理工厂的实例获取的。
【0分下载示例源码】
如何在Spring框架中使用RMI技术相关推荐
- 说说如何在 Spring 框架中使用 SpEL 表达式
在 Spring 框架的 XML 配置方式或者注解配置方式中,我们都可以使用 SpEL 表达式,它们的语法都是 #{表达式}. 1 基于 XML 配置 在 XML 配置中,我们可以通过 SpEL 表达 ...
- Spring框架中的核心技术之AOP
目录 1. 什么是AOP? 2. 实现AOP技术的框架有哪些? 2.1 Spring框架中的AOP技术 2.2 Aspectj框架 2.3 小结 3. Aspectj框架中的使用AOP的方式 4. A ...
- 如何在 Spring 生态中玩转 RocketMQ?
作者 | 通融.洛夜 来源 | 阿里巴巴云原生公众号 RocketMQ 作为业务消息的首选,在消息和流处理领域被广泛应用.而微服务生态 Spring 框架也是业务开发中最受欢迎的框架,两者的完美契合使 ...
- 如何在Spring生态中玩转RocketMQ?
简介: RocketMQ作为业务消息的首选,在消息和流处理领域被广泛应用.而微服务生态Spring框架也是业务开发中最受欢迎的框架,两者的完美契合使得RocketMQ成为Spring Messagin ...
- 如何在Spring Boot中使用TDD写出高质量的接口
本文发布于专栏Effective Java,如果您觉得看完之后对你有所帮助,欢迎订阅本专栏,也欢迎您将本专栏分享给您身边的工程师同学. 之前在<如何说服你的同事使用TDD>中介绍了为什么要 ...
- Spring框架中常用的设计模式详解
一.浅谈控制反转(IOC)与依赖注入(DI) IOC(Inversion of Control)是Spring中一个非常重要的概念,它不是什么技术,而是一种解耦的设计思想.它主要的额目的是借助于第三方 ...
- Spring框架中的设计模式(一)
设计模式有助于遵循良好的编程实践.作为最流行的Web框架之一的Spring框架也使用其中的一些. 本文将介绍Spring Framework中使用的设计模式.这是5篇专题文章的第一部分.这次我们将发现 ...
- 在Spring 框架中如何更有效的使用JDBC?
使用Spring JDBC 框架,资源管理以及错误处理的代价都会减轻.开发人员只需通过statements 和queries 语句从数据库中存取数据.Spring 框架中通过使用模板类能更有效的使用J ...
- 如何在Spring boot中修改默认端口
文章目录 介绍 使用Property文件 在程序中指定 使用命令行参数 值生效的顺序 如何在Spring boot中修改默认端口 介绍 Spring boot为应用程序提供了很多属性的默认值.但是有时 ...
- Java访问静态常量_Java如何在Spring EL中访问静态方法或常量?
在这个例子中,您将学习如何使用Spring Expression Language访问类范围的方法或常量.要访问类范围的方法或常量T(),例如,您将需要使用Spring EL的运算符T(java.la ...
最新文章
- Java学习笔记18
- python学多久可以接单-零基础小白多久能学会python
- DPDK 应用层对网卡进行配置(二十四)
- NYOJ 269 VF
- android单独刷入镜像
- C语言 回调函数 produce(arr,len,getRand)
- 柴犬为什么总是被卡住狗头?
- vue 拖拽元素到任意位置
- 苹果平板买哪款最好?
- ROST情感分析的语法规则_大数据之数据仓库Hive架构分析
- 【正点原子MP157连载】第十八章 高级定时器实验-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南
- C primer plus 第六版pdf下载
- 网络分析仪测试线损_网络分析仪测试天线隔离度
- Prolog入门教程(完整版+专家系统案例)
- 计算机安全证书有问题怎么办,此网站的安全证书有问题如何取消 此网站的安全证书有问题解决方法...
- Java-SE 学习笔记 第一章-Java历史及其基本介绍
- maven依赖名词解释
- h5实现地图定位签到
- 【AI简报20210604期】意法半导体收购Cartesiam、10个顶级开源AI项目分享
- JavaScript原型是什么
热门文章
- Javascript 使用Qunit单元测试
- 4、线程--线程同部
- mysql中权限的小知识
- 【杂题总汇】HDU多校赛第十场 Videos
- 高性能迷你React框架anujs1.0.6发布
- warning: mysql-community-libs-5.7.11-1.el7.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5
- 练习:编写循环,让用户输入内容,判断输入的内容以alex开头的,则将该字符串加上_SB结尾...
- Http代理抓包 Fiddler与Charles
- nginx源码分析——filter模块
- python __setattr__, __getattr__, __delattr__, __call__