Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。使用spring对RMI的支持,可以非常容易地构建分布式应用。这种C/S模型的访问方式,可以屏蔽掉RMI本身的复杂性,如服务端Skeleton和客户端Stub等的处理细节,这些对于服务开发和服务使用的人员来说,都是透明的,无需过度关注,而集中精力开发你的商业逻辑。主要操作是两个方面:

在服务端:可以通过org.springframework.remoting.rmi.RmiServiceExporter可以暴露你的服务;

在客户端:可以通过org.springframework.remoting.rmi.RmiProxyFactoryBean可以使用服务端暴露的服务,非常方便。


服务端端发布服务:

1 spring配置文件spring-mvc.xml如下指定了暴露的服务的名称,通过serviceName属性注入到RmiServiceExporter中,服务名称为RmiService,客户端通过该服务名称就能够进行调用

    <!--Spring RMI 服务端配置  panqq 2017-05-17 23:13:01 -->
    <bean id="baseRmiService" class="com.rmi.RmiServiceImpl" /> 
    <bean id="baseServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter">  
        <!-- 调用Service -->  
        <property name="service" ref="baseRmiService" />
        <!-- value值是提供给客户端调用 -->  
        <property name="serviceName" value="rmiService" />
        <!-- service接口 -->  
        <property name="serviceInterface" value="com.rmi.RmiService" />
        <!-- 注册端口 -->  
        <property name="registryPort" value="8088" />
    </bean>


2  服务定义业务逻辑的接口和实现类

//定义接口
public interface RmiService {
	public String getAccessToken();
	public String getTicket() ;
	public JSONObject sendMsg(JSONObject data,String toUserId,String toOpenId,String templateId,String url);
}

//该接口的实现类
public class RmiServiceImpl implements RmiService {
    .....
}


客户端口调用服务

1 客户端client.xml配置:配置中,将一个serviceUrl和serviceInterface注入给RmiProxyFactoryBean,即可进行远程方法调用。调用示例如下所示

<!-- spring rmi 客户端配置  -->
	<bean id="rmiService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
		<!-- baseService是调用服务端serviceName的value,8088是服务端注册的端口 -->
		<property name="serviceUrl" value="rmi://localhost:8088/rmiService" />
		<!-- service接口 -->
		<property name="serviceInterface" value="com.rmi.RmiClientService" />
	</bean>


2 客户端的实现类:


public interface RmiClientService {	
	public String getAccessToken();
	public String getTicket() ;
	public JSONObject sendMsg(JSONObject data,String toUserId,String toOpenId,String templateId,String url);
}


代码实现:这样就可以实现接口映射,实现远程调用服务端接口的。可用注解方式,或者直接调用client.xml方式调用

...
public RmiClientService rmiService;
@Test
public void testMsg() {
	......
*/    	rmiService.sendMsg(data, "674581a5310145c9888cae", "oGUg1wok3VAsG6qYX1Kg1", ConStant.wechatmsgmode_rztg, "");// 发送微信消息
}


public static void main(String[] args) {  
        ApplicationContext ctx = new ClassPathXmlApplicationContext(  
                "org/xxx/xxx/xx/client.xml");  
        RmiClientService service = (RmiClientService) ctx  
                .getBean("rmiService");  
        service.sendMsg(data, "674581a5310145c9888cae", "oGUg1wok3VAsG6qYX1Kg1", ConStant.wechatmsgmode_rztg, "");// 发送微信消息 
    }