//客户端:
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的其他特性,如AOP和事务管理,来增强RMI应用的功能和健壮性。
在这个简单的例子中,我们将深入理解Spring RMI的工作原理以及如何实现一个基本的Spring RMI应用。 首先,让我们了解RMI的基本概念。RMI允许Java对象在不同的JVM之间进行通信,仿佛它们都在同一台机器上。它通过...
6. **源码分析**:在提供的压缩包文件`SpringRMI`中,可能包含了上述所有步骤的代码示例。通过阅读这些源码,你可以深入理解Spring RMI的工作原理,包括服务暴露、注册、代理创建等。 7. **工具使用**:在开发过程...
下面将详细阐述Spring RMI服务的实现原理、配置过程以及如何自动化发布服务。 首先,了解RMI的基本概念是必要的。RMI是Java提供的一种标准接口,它允许一个Java对象调用远程主机上的另一个Java对象的方法,就像调用...
Spring框架对RMI的支持使得它更易于集成到现代企业级应用中,实现了服务间的松耦合和高效通信。本文将详细讲解Spring与RMI的整合,以及如何通过"SpringRMIClient"和"SpringRMIServer"这两个示例文件实现跨项目的远程...
Spring RMI(Remote Method Invocation)是Java平台上的远程方法调用技术,结合Spring框架的特性,使得在分布式系统中实现服务间的通信变得更加便捷。本文将深入探讨Spring RMI的实用知识,包括其基本原理、配置步骤...
这些示例代码是学习和实践Spring RMI的一个很好的起点,你可以通过运行它们来深入理解这个技术的工作原理。 总的来说,Spring RMI提供了一种简单且强大的方式来实现Java应用的分布式架构,通过它可以构建高度可扩展...
在Spring框架中,远程方法调用(Remote Method Invocation, RMI)是一种...通过学习这个压缩包中的示例,开发者不仅可以掌握RMI的基本原理,还能了解到Spring如何简化这个过程,从而在实际开发中更高效地利用RMI技术。
将Spring与RMI结合使用,可以实现分布式服务的灵活构建。 首先,我们需要理解RMI的基本原理。RMI允许一个Java对象调用位于不同JVM中的另一个对象的方法。这涉及到三个主要步骤:导出远程对象、注册远程对象和调用...
在IT行业中,远程方法调用...同时,理解RMI的底层原理和Spring的相关配置,对于提升系统性能和可靠性至关重要。在实际开发中,结合源码阅读和使用工具,如IDE的调试功能,可以帮助我们更好地理解和优化RMI服务。
通过理解RMI的基本原理和Spring的相关配置,我们可以有效地实现远程服务的调用,并结合Spring的优势来管理和优化分布式系统的性能和安全性。在实际项目中,务必根据需求和环境选择合适的服务发布和调用策略,以达到...
本实验课主要涵盖了HTTP客户端与服务器以及RMI客户端和服务器的使用,旨在帮助学习者理解网络通信的基本原理和实现方式。 首先,我们来详细探讨HTTP(超文本传输协议)。HTTP是互联网上应用最广泛的一种网络协议,...
浅谈 Spring 原理 透析,IOC 和 AOP Spring 框架是一个从实际项目开发经验中抽取的,可高度重用的应用框架。它是一个轻量级容器,带有包装器,使许多不同的服务和框架更易于使用。轻量级容器接受任何 JavaBean,而...
Java RMI(远程方法调用)是Java编程语言中的一项核心技术,自JDK 1.1版本起就被引入...虽然现代的Java框架如Spring、EJB等提供了更高级别的分布式服务,但理解RMI的基本原理对于深入学习Java分布式系统仍然是必要的。
3. 集成文档:可能包含了如何将RMI与Spring框架整合的教程,指导开发者如何在Spring环境中使用RMI-IIOP实现服务的发布和消费。 4. 相关资料:可能包含了关于RMI、IIOP和CORBA的基础知识,以及相关的技术文章和研究,...
做为java分布式计算的基础框架的RMI体系,是javaEE结构的基础技术. 本课件全面讲解了RMI的一般实现,特殊问题解决及... 6.Spring中的rmi应用 7.类似RMI的相关开源技术实现 -------具体请下载附件或登陆www.NetJava.cn
RMI(Remote Method Invocation,远程方法调用)是Java平台上的一个重要特性,它允许...不过,实际应用中,还应关注RMI与其他技术(如EJB、JMS、JNDI等)的集成,以及现代Java框架(如Spring)中对RMI的支持和扩展。
作者通过源代码的阅读,剖析了Spring框架的设计原理和内部架构,带领读者深入理解Spring各个组件是如何协同工作,以及其设计决策背后的原因。这样的分析对于Java开发者深入掌握Spring框架有着极大的帮助,尤其是在...
第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 调用...