参考: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();
}
}