package com.binsoft.jshooter.impl; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import java.rmi.Naming; import com.binsoft.jshooter.ServerApplication; /** * 面向反射的应用程序封装类 用法: (1) 假设你有下面这样的一个类,但是想从另一个类中创建这个类的一个对象并且直接调用里面的方法 * * public class MyClass{ public void hello() throws Exception{ * System.out.println("Hello i am MyClass.."); } } * * 现在,请注意下面的这个类,它主要是负责创建上面所说的那个类的对象,并且直接远程调用里面的方法 public class Factory{ public * static void main(String[] args){ Application app = new * Application();//注意,这个对象没有数据类型 * app.newInstance("package.MyClass");//参数包括类名称和包名称,这样从MyClass类中创建了一个新的对象 * app.invokeMethod("hello");//调用MyClass类中的hello()无参数方法 } } * * 程序输出结果为:Hello I am MyClass * * (2) 下面再更改一下MyClass类,增加一个具有参数和返回值的方法 public class MyClass{ public void hello() * throws Exception{ System.out.println("Hello i am MyClass"); } * * public String bye(String name) throws Exception{ return "goodbye " + name; } * } * * 再更改Factory类: public class Factory{ public static void main(String[] args){ * Application app = new Application();//注意,这个对象没有数据类型 * app.newInstance("package.MyClass");//参数包括类名称和包名称,这样从MyClass类中创建了一个新的对象 * app.invokeMethod("hello");//调用MyClass类中的hello()无参数方法 * //第一个参数为方法名,第二个参数为方法的输入参数 System.out.println(app.invokeMethod("bye",new * Object[]{new String("json")}));//调用具有参数和返回值的方法,很容易给这个方法传输值并且得到返回值 * * } } * * 上面程序的输出结果为:Hello i am MyClass goodbye json * * * (3) 被调用的方法包括两个或者是两个以上的输入参数 public class MyClass{ public void hello() throws * Exception{ System.out.println("Hello i am MyClass"); } * * public String bye(String name,Integer age) throws Exception{ return * "goodbye " + name + " my age is " + age; } } * * Factory 类调整为: public class Factory{ public static void main(String[] args){ * Application app = new Application();//注意,这个对象没有数据类型 * app.newInstance("package.MyClass");//参数包括类名称和包名称,这样从MyClass类中创建了一个新的对象 * app.invokeMethod("hello");//调用MyClass类中的hello()无参数方法 * //第一个参数为方法名,第二个参数为方法的输入参数 System.out.println(app.invokeMethod("bye",new * Object[]{new String("json"),new Integer(12) * }));//调用具有参数和返回值的方法,很容易给这个方法传输值并且得到返回值 * * } } * * (4) 为类中属性赋值 * * public Class MyClass{ public String name; } * * Factory 类调整为: public class Factory{ public static void main(String[] args) * throws Exception{ Application app = new Application();//注意,这个对象没有数据类型 * app.newInstance("package.MyClass");//参数包括类名称和包名称,这样从MyClass类中创建了一个新的对象 * app.setFieldValue("name",new String("bin")); * System.out.println(app.getFieldValue("name"));//程序输出结果为:bin } } * * * (5)得到类中所有方法的类型和名称 * * public class MyClass{ public void hello() { System.out.println("hello"); } * * public void bye(){ System.out.println("bye"); } * * } * * * public Class Factory{ public static void main(String[] args) throws * Exception{ Application app = new Application(); * app.newInstance("package.MyClass"); * * ArrayList namesList = app.getMethodNames(); int size = namesList.size(); * for(int i = 0; i < size; i++){ System.out.println(namesList.get(i)); } * * } } * * (6) 通过有参数的构造函数自动创建被调用对象 public class Factory{ public static void * main(String[] args) throws Exception{ Application app = new * Application();//注意,这个对象没有数据类型 app.newInstance("package.MyClass",new * Object[]{new String("bin"),new * Integer(12)});//参数包括类名称和包名称,这样从MyClass类中创建了一个新的对象 } } * * * (7)在network 中分配使用已经创建的Application类 * * Server端: public class MyClass{ public void hello(){ * System.out.println("hello"); } } * * 现在客户端想用这个已经存在在Server端的MyClass对象,那么在服务器端的代码如下: public class Factory{ public * static void main(String[] args) throws Exception{ Application app = new * Application(); app.distribute(1099,"test"); } } * * 上面的代码就会把app 对象发布到网络上,如果网络没有问题的下,程序的输出结果为: Service Name: test Port Number : * 1099 "test"字符串就像一个主键一样,客户端必须知道这个值 * * Client端代码如下: * * public class Client{ public static void main(String[] args) throws Exception{ * ServerApplication sapp = new * Application().receive("127.0.0.1","test");//得到服务器端发布的MyClass * ,并且客户端是没有MyClass这个类的 sapp.newInstance("MyClass");===>app.newInstance * sapp.invokeMethod("hello");//这个程序不会在客户端创建任何输出的,但是在服务器端输出结果 } } * * @author bin * */ public class Application extends UnicastRemoteObject implements ServerApplication { private Object object; /** * @throws RemoteException */ public Application() throws RemoteException { super(); } /** * * @param port_number * @param service_name * @return * @throws Exception */ public boolean distribute(int port_number, String service_name) throws Exception { System.out.println("Application Service Name: " + service_name); System.out.println("Application Port Number: " + port_number); java.rmi.registry.LocateRegistry.createRegistry(port_number); Naming.rebind(service_name, this); return true; } /** * * @param server_name * @param service_name * @return * @throws Exception */ public ServerApplication receive(String server_name, String service_name) throws Exception { ServerApplication obj = (ServerApplication) Naming.lookup("//" + server_name + "/" + service_name); return (ServerApplication) obj; } /** * @throws java.lang.Exception * @return Object * @param field_name */ @Override public Object getFieldValue(String field_name) throws Exception { Field field = this.object.getClass().getField( field_name.trim().replaceAll(" ", "_")); return field.get(this.object); } /** * * @throws java.lang.Exception * @return ArrayList */ @SuppressWarnings("unchecked") @Override public ArrayList getFieldsNames() throws Exception { Field[] fields = object.getClass().getFields(); ArrayList afields = new ArrayList(); int i = 0; while (fields.length != i) { afields.add(fields[i].getName()); i++; } return afields; } /** * @throws java.lang.Exception * @return ArrayList */ @SuppressWarnings("unchecked") @Override public ArrayList getFieldsTypes() throws Exception { Field[] fields = object.getClass().getFields(); ArrayList afields = new ArrayList(); int i = 0; while (fields.length != i) { afields.add(fields[i].getType()); i++; } return afields; } /** * @throws java.lang.Exception * @return String */ @Override public String getInstanceAddress() throws Exception { return object.getClass().getName(); } /** * @throws java.lang.Exception * @return ArrayList */ @SuppressWarnings("unchecked") @Override public ArrayList getMethodsNames() throws Exception { Method[] methods = object.getClass().getMethods(); ArrayList amethods = new ArrayList(); int i = 0; while (methods.length != i) { amethods.add(methods[i].getName()); i++; } return amethods; } @SuppressWarnings("unchecked") @Override public ArrayList getMethodsTypes() throws Exception { Method[] methods = object.getClass().getMethods(); ArrayList amethods = new ArrayList(); int i = 0; while (methods.length != i) { amethods.add(methods[i].getReturnType()); i++; } return amethods; } /** * @throws java.lang.Exception * @return Object * @param method_name */ @Override public Object invokeMethod(String method_name) throws Exception { Method method = this.object.getClass().getMethod( method_name.trim().replaceAll(" ", "_"), null); return method.invoke(this.object, null); } /** * */ @Override public Object invokeMethod(String method_name, Object[] method_param) throws Exception { Class[] method_param_type = new Class[method_param.length]; for (int i = 0; i < method_param.length; i++) { method_param_type[i] = method_param[i].getClass(); } Method method = this.object.getClass().getMethod( method_name.trim().replaceAll(" ", "_"), method_param_type); return method.invoke(this.object, method_param); } /** * @throws java.lang.Exception * @return boolean * @param class_address */ @Override public boolean newInstance(String class_address) throws Exception { this.object = Class.forName(class_address.trim().replaceAll(" ", "_")) .newInstance(); return true; } /** * * @throws java.lang.Exception * @return boolean * @param cons_param * @param class_address */ @SuppressWarnings("unchecked") @Override public boolean newInstance(String class_address, Object[] cons_param) throws Exception { Class[] cons_param_type = new Class[cons_param.length]; for (int i = 0; i < cons_param.length; i++) { cons_param_type[i] = cons_param[i].getClass(); } Constructor method = Class.forName( class_address.trim().replaceAll(" ", "_")).getConstructor( cons_param_type); this.object = method.newInstance(cons_param); return true; } /** * @throws java.lang.Exception * @return boolean * @param field_param * @param field_name */ @Override public boolean setFieldValue(String fieldName, Object fieldParam) throws Exception { Field field = this.object.getClass().getField( fieldName.trim().replaceAll(" ", "_")); field.set(this.object, fieldParam); return true; } /** * * @param object * @return * @throws Exception */ public boolean setObject(Object object) throws Exception { this.object = object; return true; } /** * * @return * @throws Exception */ public Object getObject() throws Exception { return object; } }