`

Spring RMI的实现原理

 
阅读更多
//客户端:

package com.service.client;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.concurrent.ConcurrentHashMap;

import com.service.export.RemoteMethodWapper;
import com.service.export.RemoteObject;

public class RMIClientBeanFactory implements InvocationHandler {

    private ConcurrentHashMap<Class<?>, ProxyAndRemoteBean> cache;

    public RMIClientBeanFactory() {
        cache = new ConcurrentHashMap<Class<?>, ProxyAndRemoteBean>();
    }

    /**
     * 获取远程对象
     * 
     * @param ins
     * @param url
     * @return
     */
    public Object getRemoteObject(Class<?> ins, String url) {
        if (!cache.contains(ins)) {
            try {
                Remote remote = Naming.lookup(url);
                Object proxy = Proxy.newProxyInstance(ins.getClassLoader(),new Class[] { ins }, this);
                ProxyAndRemoteBean bean = new ProxyAndRemoteBean(proxy, remote);
                cache.put(ins, bean);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (RemoteException e) {
                e.printStackTrace();
            } catch (NotBoundException e) {
                e.printStackTrace();
            }
        }
        return cache.get(ins).getProxy();
    }

    @Override
    public Object invoke(Object arg0, Method method, Object[] params)
            throws Throwable {
        System.out.println("[intercepter] call method:" + method.getName());
        Object obj = cache.get(method.getDeclaringClass());
        if (obj instanceof ProxyAndRemoteBean) {
            ProxyAndRemoteBean bean = (ProxyAndRemoteBean) obj;
            // 如果是框架的包转类型就把方法调用包装为MethodWapper再通过MethodWapper的RMIObjWaper的call调用
            Remote remote = bean.getRemote();
            if (remote instanceof RemoteObject) {
                RemoteObject objWaper = (RemoteObject) remote;
                RemoteMethodWapper mwp = new RemoteMethodWapper(method.getName(), params,method.getParameterTypes());
                return objWaper.call(mwp);
            } else {
                // 如果是远程对象是原生的Remote对象直接调用
                return method.invoke(remote, params);
            }
        }
        return null;
    }

    public void clear() {
        cache.clear();
    }

    /**
     * 包装了远程对象和本地代理对象
     * 
     * @author Czp
     * 
     */
    private static class ProxyAndRemoteBean {

        private Object proxy;

        private Remote remote;

        public ProxyAndRemoteBean(Object proxy, Remote remote) {
            super();
            this.proxy = proxy;
            this.remote = remote;
        }

        public Object getProxy() {
            return proxy;
        }

        public Remote getRemote() {
            return remote;
        }

    }
}
//

package com.service.export;

import java.io.Serializable;

public class RemoteMethodWapper implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private String method;
    
    private Object[] params;
    
    private Class<?>[] parTypes;

    
    
    public RemoteMethodWapper(String method, Object[] params, Class<?>[] parTypes) {
        this.method = method;
        this.params = params;
        this.parTypes = parTypes;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public Object[] getParams() {
        return params;
    }

    public void setParams(Object[] params) {
        this.params = params;
    }

    public Class<?>[] getParTypes() {
        return parTypes;
    }

    public void setParTypes(Class<?>[] parTypes) {
        this.parTypes = parTypes;
    }
    
    
}
//

package com.service.export;

import java.rmi.Remote;


public interface RemoteObject extends Remote{

    Object call(RemoteMethodWapper mwp) throws Exception;
}
//

package com.service.export;

import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;



public class RemoteObjetWapper extends UnicastRemoteObject implements RemoteObject {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    protected RemoteObjetWapper() throws RemoteException {
        super();
    }

    private Object target;



    public Object getTarget() {
        return target;
    }



    public void setTarget(Object target) {
        this.target = target;
    }



    @Override
    public Object call(RemoteMethodWapper mwp) throws Exception {
        String name = mwp.getMethod();
        Method m = this.target.getClass().getDeclaredMethod(name, mwp.getParTypes());
        return m.invoke(target, mwp.getParams());
    }



}
//

package com.service.export;


public interface ServiceExport {

    /**
     * 导出一个服务
     * 
     * @param remote 要导出的对象
     * @param serviceName 服务名称
     */
    void exportRMIObject(Object remote,String serviceName);
}
//

package com.service.export;

import java.net.Inet4Address;
import java.rmi.Naming;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

public class ServiceExportImpl implements ServiceExport {


    private String baseUrl;
    /**
     * 注册指定的端口
     * 
     * @param port
     */
    public ServiceExportImpl(int port) {
        try {
            LocateRegistry.createRegistry(port);
            baseUrl = "rmi://"+Inet4Address.getLocalHost().getHostAddress()+":"+port+"/";
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 导出一个服务对象
     * 
     */
    @Override
    public void exportRMIObject(Object remote, String name) {
        try {
            Remote rmiObj = getRMIObj(remote);
            Naming.rebind(baseUrl+ name, rmiObj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 如果要导出的对象没有实现remote则包装成
     * RemoteObjetWapper再导出
     * 
     * @param remote
     * @return
     * @throws RemoteException
     */
    private Remote getRMIObj(Object remote) throws RemoteException {
        if (remote instanceof Remote) {
            return (Remote) remote;
        } else {
            RemoteObjetWapper wapperImpl = new RemoteObjetWapper();
            wapperImpl.setTarget(remote);
            return wapperImpl;
        }
    }

}
//

package com.test;

public interface CommonService {

    String sayHello(String str);
}
//

package com.test;

import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface RemoteService extends Remote {

    Serializable getObj(int i)throws RemoteException;
}
//

package com.test.impl;

import com.test.CommonService;

/**
 * 普通对象的实现不需要实现任何特定的接口,实现了
 * 对JDK RMI接口的解耦,方法不需要抛出特定的异常
 * 
 * @author Czp
 *
 */
public class CommonServiceImpl implements CommonService {

    @Override
    public String sayHello(String str) {
        System.out.println("from client:"+str);
        return "str"+str;
    }

}
//

package com.test.impl;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import com.test.RemoteService;

/**
 * 通过普通的RMI导出的服务实现类需要继承
 * UnicastRemoteObject 并且每个
 * 方法都需要抛出RemoteException
 * 
 * @author Czp
 *
 */
public class ServiceRemoteImpl extends UnicastRemoteObject implements RemoteService{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    protected ServiceRemoteImpl() throws RemoteException {
        
    }

    @Override
    public Serializable getObj(int i) throws RemoteException{
        System.out.println("ok:"+i);
        return "test:"+i;
    }

}
//

package com.test.impl;

import java.io.Serializable;

import com.service.client.RMIClientBeanFactory;
import com.test.CommonService;
import com.test.RemoteService;

public class TestClient {

    public static void main(String[] args) {
        try {
            RMIClientBeanFactory c = new RMIClientBeanFactory();
            
            //调用普通的远程对象
            String url = "rmi://10.148.144.77:6677/"+CommonService.class.getSimpleName();
            CommonService service = (CommonService) c.getRemoteObject(CommonService.class, url);
            String sayHello = service.sayHello("test");
            System.out.println("obj is:" + sayHello);
            
            //调用实现remote的远程对象与上面没有区别,框架做了透明处理
            String url2 = "rmi://10.148.144.77:6677/"+RemoteService.class.getSimpleName();
            RemoteService remote = (RemoteService) c.getRemoteObject(RemoteService.class, url2);
            Serializable rt = remote.getObj(10000);
            System.out.println(rt);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//

package com.test.impl;



import com.service.export.ServiceExport;
import com.service.export.ServiceExportImpl;
import com.test.CommonService;
import com.test.RemoteService;

public class TestService {

    public static void main(String[] args) throws Exception {
        ServiceExport export = new ServiceExportImpl(6677);
        
        //导出普通对象
        CommonService service = new CommonServiceImpl();
        export.exportRMIObject(service,CommonService.class.getSimpleName());
        System.out.println("export:"+CommonService.class.getSimpleName());
        
        //导出实现Remote的对象与上面没区别,框架做了透明处理
        RemoteService serviceRemote = new ServiceRemoteImpl();
        export.exportRMIObject(serviceRemote,RemoteService.class.getSimpleName());
        System.out.println("export:"+RemoteService.class.getSimpleName());
    }
}
分享到:
评论

相关推荐

    Spring RMI小例子

    通过这个小例子,我们可以学习到Spring RMI的基本用法,理解其工作原理,这对于构建分布式系统非常有帮助。实践中,还可以进一步探索如何结合Spring的其他特性,如AOP和事务管理,来增强RMI应用的功能和健壮性。

    spring RMI简单例子

    在这个简单的例子中,我们将深入理解Spring RMI的工作原理以及如何实现一个基本的Spring RMI应用。 首先,让我们了解RMI的基本概念。RMI允许Java对象在不同的JVM之间进行通信,仿佛它们都在同一台机器上。它通过...

    spring rmi 小例子

    6. **源码分析**:在提供的压缩包文件`SpringRMI`中,可能包含了上述所有步骤的代码示例。通过阅读这些源码,你可以深入理解Spring RMI的工作原理,包括服务暴露、注册、代理创建等。 7. **工具使用**:在开发过程...

    spring RMI 服务(自动把service发布为RMI服务)

    下面将详细阐述Spring RMI服务的实现原理、配置过程以及如何自动化发布服务。 首先,了解RMI的基本概念是必要的。RMI是Java提供的一种标准接口,它允许一个Java对象调用远程主机上的另一个Java对象的方法,就像调用...

    Spring-RMI.rar_spring rmi

    Spring框架对RMI的支持使得它更易于集成到现代企业级应用中,实现了服务间的松耦合和高效通信。本文将详细讲解Spring与RMI的整合,以及如何通过"SpringRMIClient"和"SpringRMIServer"这两个示例文件实现跨项目的远程...

    spring RMI 实用分享

    Spring RMI(Remote Method Invocation)是Java平台上的远程方法调用技术,结合Spring框架的特性,使得在分布式系统中实现服务间的通信变得更加便捷。本文将深入探讨Spring RMI的实用知识,包括其基本原理、配置步骤...

    spring RMI 远程接口调用

    这些示例代码是学习和实践Spring RMI的一个很好的起点,你可以通过运行它们来深入理解这个技术的工作原理。 总的来说,Spring RMI提供了一种简单且强大的方式来实现Java应用的分布式架构,通过它可以构建高度可扩展...

    如何在Spring框架中使用RMI技术.zip

    在Spring框架中,远程方法调用(Remote Method Invocation, RMI)是一种...通过学习这个压缩包中的示例,开发者不仅可以掌握RMI的基本原理,还能了解到Spring如何简化这个过程,从而在实际开发中更高效地利用RMI技术。

    Spring(RMI)实例

    将Spring与RMI结合使用,可以实现分布式服务的灵活构建。 首先,我们需要理解RMI的基本原理。RMI允许一个Java对象调用位于不同JVM中的另一个对象的方法。这涉及到三个主要步骤:导出远程对象、注册远程对象和调用...

    rmi实例(Spring整合)

    在IT行业中,远程方法调用...同时,理解RMI的底层原理和Spring的相关配置,对于提升系统性能和可靠性至关重要。在实际开发中,结合源码阅读和使用工具,如IDE的调试功能,可以帮助我们更好地理解和优化RMI服务。

    spring整合RMI

    通过理解RMI的基本原理和Spring的相关配置,我们可以有效地实现远程服务的调用,并结合Spring的优势来管理和优化分布式系统的性能和安全性。在实际项目中,务必根据需求和环境选择合适的服务发布和调用策略,以达到...

    HTTP客户端,HTTP服务器,RMI客户端和服务器

    本实验课主要涵盖了HTTP客户端与服务器以及RMI客户端和服务器的使用,旨在帮助学习者理解网络通信的基本原理和实现方式。 首先,我们来详细探讨HTTP(超文本传输协议)。HTTP是互联网上应用最广泛的一种网络协议,...

    浅谈 Spring 原理 透析,ioc aop

    浅谈 Spring 原理 透析,IOC 和 AOP Spring 框架是一个从实际项目开发经验中抽取的,可高度重用的应用框架。它是一个轻量级容器,带有包装器,使许多不同的服务和框架更易于使用。轻量级容器接受任何 JavaBean,而...

    RMI.rar_Java RMI_java.rmi_java.rmi.Remot_remote

    Java RMI(远程方法调用)是Java编程语言中的一项核心技术,自JDK 1.1版本起就被引入...虽然现代的Java框架如Spring、EJB等提供了更高级别的分布式服务,但理解RMI的基本原理对于深入学习Java分布式系统仍然是必要的。

    RMI-IIOP 基于SUN

    3. 集成文档:可能包含了如何将RMI与Spring框架整合的教程,指导开发者如何在Spring环境中使用RMI-IIOP实现服务的发布和消费。 4. 相关资料:可能包含了关于RMI、IIOP和CORBA的基础知识,以及相关的技术文章和研究,...

    长沙蓝杰实训java课件之 RMI技术解析(www.NetJava.cn)

    做为java分布式计算的基础框架的RMI体系,是javaEE结构的基础技术. 本课件全面讲解了RMI的一般实现,特殊问题解决及... 6.Spring中的rmi应用 7.类似RMI的相关开源技术实现 -------具体请下载附件或登陆www.NetJava.cn

    rmi.rar_rmi

    RMI(Remote Method Invocation,远程方法调用)是Java平台上的一个重要特性,它允许...不过,实际应用中,还应关注RMI与其他技术(如EJB、JMS、JNDI等)的集成,以及现代Java框架(如Spring)中对RMI的支持和扩展。

    Spring技术内幕:深入解析Spring架构与设计原理

    作者通过源代码的阅读,剖析了Spring框架的设计原理和内部架构,带领读者深入理解Spring各个组件是如何协同工作,以及其设计决策背后的原因。这样的分析对于Java开发者深入掌握Spring框架有着极大的帮助,尤其是在...

    Spring攻略(第二版 中文高清版).part1

    第1章 Spring简介 1 1.1 实例化Spring IoC容器 1 1.1.1 问题 1 1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用...

Global site tag (gtag.js) - Google Analytics