版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
之前项目用过的spring一个技术点,记录一下。
SpringRMI远程调用,首先有两个端 服务端提供服务接口和内部具体实现,而客户端用相同技术去调用该服务端接口。
大致流程:
- 服务端定义远程访问接口,并有具体的类去实现接口功能。
- 再通过org.springframework.remoting.rmi.RmiServiceExporter类去暴露接口。
- 客户端定义相同接口,这里不需要实现类。
- 通过org.springframework.remoting.rmi.RmiProxyFactoryBean类去调用远程的服务接口。
-
服务端代码
接口类和实现类
//接口类
package service;
import cn.hpc.ssm.pojo.User;
//RMI服务接口
public interface IHelloService {
public String sayHello(String something);
public User sendUser(User user);
}
//实现类
package service;
import java.util.Date;
import org.springframework.stereotype.Service;
import cn.hpc.ssm.pojo.User;
@Service
public class IHelloImpl implements IHelloService{
//接收一个User对象,进行修改后返回
@Override
public User sendUser(User user) {
User u =user;
u.setId(44);
u.setCreatedate(new Date());
u.setLoginname("hpc");
u.setPassword("123456");
u.setStatus(2);
System.out.println(u);
return u;
}
//打印参数,并返回一串字符串
@Override
public String sayHello(String something) {
System.out.println("接收客户端信息:"+something);
return "你好我是服务端aaaaa!";
}
}
POJO的User对象代码(这里一定要实现Serializable接口)
package cn.hpc.ssm.pojo;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable{
/**
* 序列化ID
*/
private static final long serialVersionUID = 1L;
private Integer id;
private Date createdate;
private String loginname;
private String password;
private Integer status;
private String username;
/** 此处省略set/get方法 **/
@Override
public String toString() {
return "User [id=" + id + ", createdate=" + createdate + ", loginname=" + loginname + ", password=" + password
+ ", status=" + status + ", username=" + username + "]";
}
}
spring配置暴露接口,applicationContext-service.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 配置包扫描器,扫描带@Service注解的类
<context:component-scan base-package="cn.hpc.ssm.service"/>
-->
<!-- 接口实现类 -->
<bean id="iHelloImpl" class="service.IHelloImpl"></bean>
<!-- 配置RMI-->
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<!-- 设置RMI服务名,做为RMI客户端调用接口 -->
<property name="serviceName" value="hello"></property>
<!-- 对应接口实现类 -->
<property name="service" ref="iHelloImpl"></property>
<!-- RMI服务接口路径 -->
<property name="serviceInterface" value="service.IHelloService"></property>
<!-- 设置RMI服务端口 -->
<property name="registryPort" value="8086"></property>
</bean>
</beans>
-
客户端代码
定义跟服务端相同的接口类(这里不需要实现类)
package service;
import cn.hpc.ssm.pojo.User;
public interface IHelloService1 {
public String sayHello(String something);
public User sendUser(User user);
}
定义相同的User对象
/** 这里代码省略 **/
通过spring配置访问服务端接口,service.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 配置包扫描器,扫描带@Service注解的类
<context:component-scan base-package="cn.hpc.ssm.service"/>
-->
<!-- 扫描包基础目录 -->
<context:component-scan base-package="service"></context:component-scan>
<!-- 客户端调用 -->
<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<!-- 根据服务端的serviceName(服务名)和registryPort(端口)组成的访问地址 -->
<property name="serviceUrl" value="rmi://localhost:8086/hello"></property>
<property name="serviceInterface" value="service.IHelloService1"></property>
<!-- 预查找远程对象 默认为true -->
<property name="lookupStubOnStartup" value="false"/>
<!-- 是否刷新远程调用缓存的stub -->
<property name="refreshStubOnConnectFailure" value="true"></property>
</bean>
</beans>
上面的lookupStubOnStartup预查找远程对象,设置为true的话 当客户端初始化spring容器就会预加载服务端接口,此时如果服务端未启动就会报错。
客户端编写测试类
package cn.hpc.ssm.controller;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.IHelloService1;
import cn.hpc.ssm.pojo.User;
public class test1 {
@Test
public void demo1() {
ApplicationContext context =new ClassPathXmlApplicationContext("classpath:service.xml");
IHelloService1 service =context.getBean(IHelloService1.class);
User u =new User();
u.setUsername("王大锤");
System.out.println(service.sendUser(u));
// System.out.println(service.sayHello("我是小虎啊啊啊啊"));;
}
}
-
测试结果
客户端
客户端这里在测试类中新User对象只有【username】属性为王大锤,而其他属性则是接口返回的值。
服务端
服务类这里的实现类则打印出了原本没有设值的【username】为王大锤。