Java远程方法调用中动态代理类的使用

本文详细介绍了如何使用动态代理实现客户端通过网络调用服务端的方法,包括客户端和服务端的代码实现,以及远程调用的具体流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:http://book.youkuaiyun.com/bookfiles/269/10026911928.shtml
客户端 和 服务端公用文件
share
    |__call
    |       |__Call.java
    |__service
             |__HelloService.java
客户端代码
locale
    |__client
             |__SimpleClient.java
             |__ProxyFactory.java
             |__TcpConnector.java
服务端代码
remote
     |__server
     |        |__SimpleServer.java
     |__service
              |__HelloServiceImpl.java
程序实现目标
    客户端通过动态代理类调用服务端HelloServiceImpl.java 中的方法

 

// share.call.Call.java
package share.call;

import java.io.Serializable;

/**
 *@date 2010-3-13 下午04:32:04
 *@author dycc
 *@file share.call.Call.java
 */
public class Call implements Serializable{
	/**
     * 
     */
    private static final long serialVersionUID = 1L;
	private String className;
	private String methodName;
	@SuppressWarnings(value="unchecked")
	private Class[] paramTypes;
	private Object[] params;
	private Object result;
	
	public Call(){
	}
	@SuppressWarnings(value="unchecked")
	public Call(String className,String methodName,
			Class[] paramTypes,Object[] params){
		this.className = className;
		this.methodName = methodName;
		this.paramTypes = paramTypes;
		this.params = params;
	}
	public String getClassName() {
    	return className;
    }
	public void setClassName(String className) {
    	this.className = className;
    }
	public String getMethodName() {
    	return methodName;
    }
	public void setMethodName(String methodName) {
    	this.methodName = methodName;
    }
	@SuppressWarnings(value="unchecked")
	public Class[] getParamTypes() {
    	return paramTypes;
    }
	@SuppressWarnings(value="unchecked")
	public void setParamTypes(Class[] paramTypes) {
    	this.paramTypes = paramTypes;
    }
	public Object[] getParams() {
    	return params;
    }
	public void setParams(Object[] params) {
    	this.params = params;
    }
	public Object getResult() {
    	return result;
    }
	public void setResult(Object result) {
    	this.result = result;
    }
	public String toString(){
		StringBuffer sb = new StringBuffer();
		sb.append("{className=" + className);
		sb.append(",methodName=" + methodName);
		sb.append(",result=" + result);
		sb.append("}");
		return sb.toString();
	}
}

// share.service.HelloService.java
package share.service;

import java.util.Date;

/**
 *@date 2010-3-13 下午04:29:29
 *@author dycc
 *@file share.service.HelloService.java
 */
public interface HelloService {
	public String echo(String msg);
	public Date getTime();
}

// locale.client.SimpleClient.java
package locale.client;

import share.service.HelloService;

/**
 *@date 2010-3-13 下午04:58:48
 *@author dycc
 *@file locale.client.SimpleClient.java
 */
public class SimpleClient {
	/**
	 * 通过代理类调用远程方法
	 */
	public void invoke(){
		HelloService hello = (HelloService)ProxyFactory.getProxy(
				HelloService.class,"remote.service.HelloServiceImpl",
				"localhost", 8002);
		String result = hello.echo("music");
		System.out.println("result=" + result);
	}
	
	public static void main(String[] args){
		SimpleClient client = new SimpleClient();
		client.invoke();
	}
}

// locale.client.ProxyFactory.java
package locale.client;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.RemoteException;

import share.call.Call;

/**
 *@date 2010-3-13 下午08:21:01
 *@author dycc
 *@file locale.client.ProxyFactory.java
 */
public class ProxyFactory {
	/**
	 * 获取动态代理类
	 * @param classType 接口
	 * @param className 实现类名称 
	 * @param ip        ip 地址
	 * @param port      端口
	 * @return
	 */
	@SuppressWarnings(value="unchecked")
	public static Object getProxy(Class classType,
			final String className,
			final String ip,final int port){
		// start
		InvocationHandler handler = new InvocationHandler(){
			public Object invoke(Object proxy, Method method, Object[] args)
			        throws Throwable {
				System.out.println("--- before " + method.getName() + "---");
			    TcpConnector connector = new TcpConnector(ip, port);
			    Call call = new Call(className,method.getName(),
			    		method.getParameterTypes(),args);
			    call = (Call)connector.invoke(call);
			    Object result = call.getResult();
			    if(result instanceof Throwable){
			    	return new RemoteException(method.getName() + "invoke failed",
			    			(Throwable)result);
			    }
			    System.out.println("--- after " + method.getName() + "---");
			    connector.close();
			    return result;
			}
		};
		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
				new Class[]{classType}, handler);
	}
}

// locale.client.TcpConnector.java
package locale.client;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

/**
 *@date 2010-3-13 下午08:25:04
 *@author dycc
 *@file locale.client.TcpConnector.java
 */
public class TcpConnector {
	private Socket socket;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	/**
	 * 构造器
	 * @param ip
	 * @param port
	 * @throws IOException
	 */
	public TcpConnector(String ip,int port)throws IOException{
		socket = new Socket(ip,port);
	}
	/**
	 * 调用远程方法
	 * @param obj
	 * @throws IOException
	 */
	public Object invoke(Object obj)throws IOException,ClassNotFoundException{
		if(out == null){
			out = new ObjectOutputStream(socket.getOutputStream());
		}
		out.writeObject(obj);
		out.flush();
		if(in == null){
			in = new ObjectInputStream(socket.getInputStream());
		}
		return in.readObject();
	}
	/**
	 * 关闭连接
	 */
	public void close(){
		try{
			if(in != null){
				in.close();
			}
			if(out != null){
				out.close();
			}
			if(socket != null){
				socket.close();
			}
		} catch(Exception e){
		}
	}
}

// remote.server.SimpleServer.java
package remote.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import share.call.Call;


/**
 *@date 2010-3-13 下午04:38:44
 *@author dycc
 *@file remote.server.SimpleServer.java
 */
public class SimpleServer {
	private Map<String,Object> map_objs = new HashMap<String,Object>();
	private ObjectInputStream in;
	private ObjectOutputStream out;
	/**
	 * 服务端在 8002 端口监听客户端请求
	 * @throws IOException
	 */
	public void service()throws IOException{
		ServerSocket server_socket = new ServerSocket(8002);
		System.out.println("----- server started. -----");
		while(true){
			try{
    			Socket socket = server_socket.accept();
    			// ObjectInputStream 会发生阻塞!!
    			in = new ObjectInputStream(socket.getInputStream());
    			Call call = (Call)in.readObject();
    			System.out.println("-- get call [" + call.getClassName()
    					           + ":" + call.getMethodName() + "]");
    			call = invoke(call);
    			out = new ObjectOutputStream(socket.getOutputStream());
    			out.writeObject(call);
    			out.flush();
			} catch(Exception e){
				e.printStackTrace();
			} finally{
				try{
					if(in != null){
						in.close();
					}
					if(out != null){
						out.close();
					}
				} catch(Exception e){
				}
			}
		}
	}
	/**
	 * 调用 call 所指定的的方法
	 * @param call
	 * @return
	 */
	public Call invoke(Call call){
		Object obj = map_objs.get(call.getClassName());
		if(obj == null){
			try {
	            obj = Class.forName(call.getClassName()).newInstance();
	            map_objs.put(call.getClassName(), obj);
            } catch (Exception e) {
	            e.printStackTrace();
            }
		}
		try {
	        Method method = obj.getClass().getMethod(
	        			    call.getMethodName(),
	        			    call.getParamTypes());
	        Object result = method.invoke(obj, call.getParams());
	        call.setResult(result);
        } catch (Exception e) {
	        e.printStackTrace();
        }
		return call;
	}
	
	public static void main(String[] args)throws Exception{
		SimpleServer server = new SimpleServer();
		server.service();
	}
}

// remote.service.HelloServiceImpl.java
package remote.service;

import java.util.Date;

import share.service.HelloService;

/**
 *@date 2010-3-13 下午04:30:44
 *@author dycc
 *@file remote.service.HelloServiceImpl.java
 */
public class HelloServiceImpl implements HelloService{
	public String echo(String msg) {
	    return "echo:" + msg;
	}
	public Date getTime() {
	    return new Date();
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值