rmi

RMI(Remote Method Invocation,远程方法调用)是Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力.RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。

RMI主要采用Java对象序列化技术和TCP协议进行远程通信. 由于不是HTTP协议,不能穿越防火墙。
JRMP: JRMP是RMI最早的实现,也是Java中默认的实现,只能在Java语言中使用。
CORBA:CORBA也是基于RMI技术发展起来的,采用了基于HTTP的IIOP协议,以及接口定义语言IDL,不但可以跨越防火墙,还可以支持跨语言的调用。 EJB: EJB也是一种RMI技术,只不过底层使用了基于HTTP的IIOP协议。

调用过程:
rmi_第1张图片
在此过程中,参数和返回值需要分别进行Java的序列化和反序列化.

JAVA Project 1:
Server

/**
 * @author:Security
 * 创建日期:2013-9-3
 */
public interface ISecurity extends Remote {
	//需要远程调用的方法必须抛出RemoteException异常
	public String sayHello(String name) throws RemoteException;
}
/**
 * @author:Security
 * 创建日期:2013-9-3
 */
public class SecurityImpl extends UnicastRemoteObject implements ISecurity {

	private static final long serialVersionUID = 8454617418203467210L;

	//因为UnicastRemoteObject的构造方法抛出了RemoteException异常,
	//因此这里默认的构造方法必须写,必须声明抛出RemoteException异常
	public SecurityImpl() throws RemoteException {}

	@Override
	public String sayHello(String name) throws RemoteException {
		return "hello " + name;
	}
}
/**
 * @author:zhouyanghong
 * 创建日期:2013-9-3
 * 功能:创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中
 */
public class SecurityServer {

	public static void main(String[] args) {
		try { 
            //创建一个远程对象 
			ISecurity security = new SecurityImpl(); 
            //本地主机上的远程对象注册表Registry的实例,并指定端口
            LocateRegistry.createRegistry(8888); 

            //把远程对象注册到RMI注册服务器上,并命名为Security 
            //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略) 
            Naming.bind("rmi://localhost:8888/SecurityRMI",security); 
            System.out.println("INFO:远程ISecurity对象绑定成功!"); 
        } catch (RemoteException e) { 
            System.out.println("创建远程对象发生异常!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("发生重复绑定对象异常!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("发生URL畸形异常!"); 
            e.printStackTrace(); 
        } 
	}
}
JAVA Project 2:
Client
/**
 * @author:Security
 * 创建日期:2013-9-3
 */
public interface ISecurity extends Remote {
	//需要远程调用的方法必须抛出RemoteException异常
	public String sayHello(String name) throws RemoteException;
}
/**
 * @author:Security
 * 创建日期:2013-9-3
 */
public class SecurityClient {
	public static void main(String[] args) {
		try { 
            //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 
			ISecurity security =(ISecurity) Naming.lookup("rmi://localhost:8888/SecurityRMI");
			System.out.println(security.sayHello("java"));
        } catch (NotBoundException e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e) { 
            e.printStackTrace();   
        } 
	}
}


Spring Remoting

Spring Remoting是Spring对已有远程通信技术做的集成,支持以下技术:
1. RMI:通过RmiProxyFactoryBeanRmiServiceExporter支持传统的RMI(即实现了Remote借口),并且支持透明的RMI调用(任何POJO)
2. Spring HttpInvoker: Spring自己的远程调用技术,基于HTTP和Java的序列化。支持任何Java接口,对应的类是HttpInvokerProxyFactory/HttpInvokerServiceExporter。要求通信双方不但是Java,而且必须使用Spring框架。
3. HessianBurlap:通过HessianProxyFactoryBean、BurlapProxyFactoryBean等支持著名的Hessian/Burlap协议。
4. 当然,Spring Remoting也支持非RMI的远程调用,如JMSWebService。 Spring Remoting采用了一些最佳实践,如采用代理和缓存机制,因而在性能上略有提升。

新建Maven Web项目:

rmi_第2张图片

ISecurityService接口:

public interface ISecurityService {
	public String queryUser() throws Exception;
}
SecurityServiceImpl实现类:
@Service
public class SecurityServiceImpl implements ISecurityService {

	@Override
	public String queryUser() throws Exception {
		return "query seccuss";
	}
}
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tool="http://www.springframework.org/schema/tool"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
  		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd
  		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
  		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  		http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
  		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">	
  		
 	<context:annotation-config/>
 	
 	<!-- 定义扫描根路径为org.lazicats.ecos的类-->
	<context:component-scan base-package="org.lazicats.ecos" />
	
	<!-- 订单模块服务 -->
	<import resource="classpath:rmiservice/security-service.xml"/>
 </beans>
security-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tool="http://www.springframework.org/schema/tool"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
  		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd
  		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
  		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  		http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
  		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">	
  	
  	<!--服务端--> 
	<bean id="securityService" class="org.lazicats.ecos.service.impl.SecurityServiceImpl" scope="prototype"/>
		
	<!-- RMI服务 -->
	<bean id="security" class="org.springframework.remoting.rmi.RmiServiceExporter">
		<!-- 服务类 -->
		<property name="service" ref="securityService" />
		<!-- 服务名 -->
		<property name="serviceName" value="securityService" />
		<!-- 服务接口 -->
		<property name="serviceInterface" value="org.lazicats.ecos.service.ISecurityService" />
		<!-- 服务端口 -->
		<property name="registryPort" value="1019" />
	</bean>
 </beans>	
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath*:applicationContext*.xml
		</param-value>
	</context-param>
  	
  	<!-- Spring 启动	-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
    
    <!-- 统一编码过虑器	-->
	<!-- Character Encoding filter -->
	<filter>
		<filter-name>SetCharacterEncoding</filter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>SetCharacterEncoding</filter-name>
		<url-pattern>*.ihtml</url-pattern>
	</filter-mapping>
	
	<servlet>
  		<servlet-name>mvcDispatcher</servlet-name>
  		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:dispatcher-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
  	</servlet>
  	<servlet-mapping>
  		<servlet-name>mvcDispatcher</servlet-name>
  		<url-pattern>*.ihtml</url-pattern>
  	</servlet-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tool="http://www.springframework.org/schema/tool"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
  		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd
  		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
  		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  		http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
  		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
	
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="contentType" value="text/html; charset=utf-8"/>
		<property name="prefix" value="/pages/erp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
	
	<!-- 字符编码配置 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="messageConverters">
			<list>
				<bean class="org.springframework.http.converter.StringHttpMessageConverter">
					<property name="supportedMediaTypes">
						<list> <value>text/plain;charset=UTF-8</value> </list>
					</property>
				</bean>
			</list>
		</property>
	</bean>
	
	<!-- 注解支持 -->
	<mvc:annotation-driven />
	
	<!-- 对controller包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
	<context:component-scan base-package="org.lazicats.ecos" />
</beans>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>rmi</name>
  <groupId>org.ecos</groupId>
  <artifactId>rmi</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.7</version>
        <configuration>
          <connectors>
            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
              <port>8888</port>
              <maxIdleTime>30000</maxIdleTime>
            </connector>
          </connectors>
          <webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}</webAppSourceDirectory>
          <contextPath>/</contextPath>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <dependencies>
  	<!-- spring framework -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-asm</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
			<type>jar</type>
			<scope>compile</scope>
		</dependency>
  </dependencies>
  
  <properties>
		<!-- 项目编码设置,仅对maven有效,方便CI -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<!-- Framework dependency version -->
		<spring.version>3.1.3.RELEASE</spring.version>
  </properties>
</project>
在容器中启动项目

调用方:
rmi_第3张图片

ISecurityService接口:

public interface ISecurityService {
	public String queryUser() throws Exception;
}
application_remote_client.properties
security_common_remote_url = rmi://localhost:1019
applicationContext-interface-adapter-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:tool="http://www.springframework.org/schema/tool"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="
  		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-3.1.xsd
  		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
  		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
  		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 
 	<!-- 加载properties文件 -->
 	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
			 	<value>classpath*:*.properties</value>
			</list>
		</property>
	</bean>
	
   <!-- Security RMI   -->
    <bean id="securityService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"> 
        <property name="serviceUrl" value="${security_common_remote_url}/securityService"/> 
        <property name="serviceInterface" value="org.lazicats.ecos.service.ISecurityService"/> 
    </bean> 
</beans>
SecurityServiceTest测试类:
启动RMI服务,运行测试类
package org.lazicats.ecos.service;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author:zhouyanghong
 * 创建日期:2013-9-2
 */
public class SecurityServiceTest {
	ApplicationContext context = null;
	ISecurityService securityService = null;
	@Before
	public void setUp() throws Exception {
		
		context = new ClassPathXmlApplicationContext("applicationContext-interface-adapter-client.xml");	
		securityService = (ISecurityService) context.getBean("securityService");
	}	
	
	@Test
	public void testRmi() throws Exception{
		String message = securityService.queryUser();
		System.out.println(message);
	}
}

你可能感兴趣的:(rmi)