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协议。
调用过程:
在此过程中,参数和返回值需要分别进行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:
/** * @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(); } } }
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>在容器中启动项目
ISecurityService接口:
public interface ISecurityService { public String queryUser() throws Exception; }application_remote_client.properties
security_common_remote_url = rmi://localhost:1019applicationContext-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测试类:
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); } }