spring05-RMI---G05

2019-07-17  本文已影响0人  小山居

spring05-RMI

一. 远程方法调用 RMI

Java RMI 指的是远程方法调用 (Remote Method
Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个
Java 虚拟机中的对象上的方法。JVM 可以位于相同或不同计算机上,在多个 JVM
中,一个 JVM 可以调用存储在其它 JVM 的对象的方法。
RMI 是 Java 编程语言里, 一种用于实现远程过程调用的应用程序编程接口,
它是
客户机上运行的程序可以调用远程服务器上的对象, 远程方法调用特性使 Java
编程人员能够在网络环境中分布操作。

RMI 全部的宗旨就是尽可能简化远程接口对象的使用。
Java RMI 极大地依赖于接口, 在需要创建一个远程对象的时候,
程序员通过传递一个接口来隐藏底层的实现细节,
客户端得到的远程对象句柄正好与本地的根代码连接,
由后者负责透过网络通信。 这样一来,
程序员只需关心如何通过自己的接口句柄发送消息。Spring 的优势除了 IOC 和
AOP 外, 还提供了简易的服务抽象。 如远程 rmi 调用。

远程方法调用, 即 Java RMI(java Remote Method Invocation)。

RMI 底层封装了 Socket 反射机制。 java 语言当中 分布式的基础!!!实现 java
之间的互相访问。

RMI 本质就是使用代理类来封装 Socket 的通信细节! ! RMI 的 API
帮组我们创建一个代理类及其内容! ! 使用这个代理类实例就可以远程通信。

1.RMI 实现常用 API

1).Remote 接口: 每一个要暴露出去的 java 类, 都需要实现 Remote 接口,
并且所有的方法必须抛出 RemoteException

2).UnicastRemoteObject 类:服务端程序的实现方案之一就是继承这个类,
无参构造器
也要抛出 RemoteException

3).LocateRegistry 类创建能在特定接口接受调用远程对象注册服务程序。

public static Registry createRegistry(int port) throws RemoteException
4).Naming
类提供了存储和获得远程对象注册服务程序中的远程对象进行引用的方法

public static Remote lookup(String name) throws
NotBoundException,MalformedURException,ReoteException
public static void bind(String name,Remote obj) throws
AlreadyBoundException,MalforedURException,RemoteException

2JAVA RMI 实例

通过maven多模块实现rmi,模拟多个服务器

image.png


1)共同.接口定义IHelloService


/**
 * 1.接口继承Remote
 * 2.对外服务方法声明 RemoteException 异常
 *
 */
public interface IHelloService extends Remote{
    public String sayHello(String msg) throws RemoteException;
}


2).服务器端rmi-server模块

2.1接口具体服务实现类包:com.shsxt.service,impl----HelloServiceImpl.java

/**
 *  1、继承 UnicastRemoteObject
 *  2、提供 无参构造 对外声明 RemoteException
 *
 */
public class HelloServiceImpl extends UnicastRemoteObject implements IHelloService {
    private static final long serialVersionUID = -5672932066566630040L;

    public HelloServiceImpl() throws RemoteException {
    }
    @Override
    public String sayHello(String msg) throws RemoteException{
        System.out.println("服务器端接收到消息:"+msg);
        return "hello:"+msg;
    }

}


2.2发布服务, 对外提供相应服务test包---com.shsxt.Publish.java

/**
 * 发布服务,对外提供相应服务
 */
public class Publish {

    public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {
         //注册端口
        LocateRegistry.createRegistry(8888);
        //对外发布rmi服务
        Naming.bind("rmi://127.0.0.1:8888/hello", new HelloServiceImpl());
    }
}


3).客户端rmi-client模拟

3.1.客户端与服务端声明相同接口
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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring_rmi</artifactId>
        <groupId>com.shsxt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-client</artifactId>

    <name>rmi-client</name>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
<!--引入共同接口配置-->
        <dependency>
            <groupId>com.shsxt</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>



    </dependencies>


</project>


3.2.客户端查找并调用远程服务com.shsxt.Test类

/**
 * 客户端查找并调用远程服务
 */
public class Test {
    public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
        IHelloService helloService=(IHelloService) Naming.lookup("rmi://127.0.0.1:8888/hello");
        System.out.println(helloService.sayHello("im win10"));
    }

}



4)远程调用RMI测试结果

image.png

3 Spring 实现远程方法调用

使用 spring 的 RMI, 提供的服务简单方便, 不用继承接口 和指定的类,
不用抛出异常。

image.png

1.引入spring配置

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.shsxt</groupId>
    <artifactId>spring11-rmi</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>rmiapi</module>
        <module>rmiserver</module>
        <module>rmiclient</module>
    </modules>


</project>

1)接口配置rmi-api

1.1接口声明com.shsxt.service---IHelloService.java

/**
 * 1.接口继承Remote
 * 2.对外服务方法声明 RemoteException 异常
 *
 */
public interface IHelloService extends Remote{
    public String sayHello(String msg) throws RemoteException;
}


2)服务端接口声明

2.1pom.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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring11-rmi</artifactId>
        <groupId>com.shsxt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-server</artifactId>

    <name>rmi-server</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.shsxt</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
    </dependencies>

</project>


2.2.接口实现 com.shsxt.service.impl---HelloServiceImpl.java


@Service
public class HelloServiceImpl implements IHelloService {
    @Override
    public String sayHello(String msg) {
        System.out.println("服务器端收到信息:"+msg);
        return "hello:"+msg;
    }
}


2.3resources----spring.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:context="http://www.springframework.org/schema/context"
       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">
    <!-- 定义扫描范围 -->
    <context:component-scan base-package="com.shsxt"></context:component-scan>

    <!-- 加入rmi相关配置  -->
    <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName" value="hello"></property>
        <property name="service" ref="helloServiceImpl"></property>
        <property name="serviceInterface" value="com.shsxt.service.IHelloService"></property>
        <property name="registryPort" value="1199"></property>
    </bean>
</beans>


2.4.对外发布远程服务test---com.shsxt.Publist

public class Publist {

    public static void main(String[] args) {
        /**
         * 启动spring ioc容器 ,并发布对应服务
         */
        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
    }
}


3)客户端调用

3.1pom.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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring11-rmi</artifactId>
        <groupId>com.shsxt</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi-client</artifactId>

    <name>rmi-client</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.shsxt</groupId>
            <artifactId>rmi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
    </dependencies>

</project>


3.2.接口声明com.shsxt.service.impl. UserServiceImpl.java


@Service
public class UserServiceImpl {
    @Resource
    private IHelloService helloService;
    
    public void test() throws RemoteException {
        System.out.println(helloService.sayHello("im win10"));
    }
}


3.3spring.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:context="http://www.springframework.org/schema/context"
       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">

    <!-- 定义扫描范围 -->
    <context:component-scan base-package="com.shsxt"></context:component-scan>

    <bean class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:1199/hello"></property>
        <property name="serviceInterface" value="com.shsxt.service.IHelloService"></property>
    </bean>
</beans>


3.4.客户端使用远程接口方法服务test---com.shsxt.Test


//客户端发送请求
public class Test {

    public static void main(String[] args) throws RemoteException {
        ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
        UserServiceImpl userServiceImpl=  (UserServiceImpl) ac.getBean("userServiceImpl");
        userServiceImpl.test();

    }

}


3.5客户端测试

image.png
上一篇下一篇

猜你喜欢

热点阅读