//客户端: 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()); } }