一、Java的动态代理对象
实现代码如下:
1.接口类MyService
package hdfs.proxy; public interface MyService { public void method1(); public void method2(); }
2.接口实现类MyServiceImpl
package hdfs.proxy; public class MyServiceImpl implements MyService { @Override public void method1() { System.out.println("************ method1 ***************"); } @Override public void method2() { System.out.println("************ method2 ***************"); } }
3.测试类TestMain
package hdfs.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class TestMain { public static void main(String[] args) { //创建真正的对象 MyService obj = new MyServiceImpl(); //obj.method1(); ---> 都是直接调用真正对象 //obj.method2(); ---> 都是直接调用真正对象 /* * Object Proxy.newProxyInstance(ClassLoader loader, 类加载器,代理对象跟真正对象是同一个类加载器 Class<?>[] interfaces, 真正对象实现的接口 InvocationHandler h) 如何处理客户端的调用 返回一个代理对象 */ //生成obj的代理对象,并且重新method2的逻辑 MyService proxy = (MyService) Proxy.newProxyInstance(TestMain.class.getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 如何处理客户端的调用 if(method.getName().equals("method2")){ //客户端调用了method2 System.out.println("in proxy method2"); return null; }else{ //其他方法不感兴趣 return method.invoke(obj, args); } } }); //通过代理对象进行调用 proxy.method1(); proxy.method2(); } }
console:
二、RPC:远程过程调用
1.服务端:发布一个接口(MyBusiness)到RPC Server上
实现类:MyBusinessImpl
如果要把程序发布到Hadoop的RPC Server上,必须实现一个接口VersionedProtocol
2.客户端:调用服务器端的功能
得到一个签名必须与服务器发布的签名的一样
得到服务器端的对象(代理对象)
实现代码如下:
3.MyBusiness
package demo.proxy.rpc.server; import org.apache.hadoop.ipc.VersionedProtocol; public interface MyBusiness extends VersionedProtocol{ //指定一个版本号,使用这个版本号来创建签名 public static long versionID = 1l; //定义自己的业务方法 public String sayHello(String name); }
4.MyBusinessImpl
package demo.proxy.rpc.server; import java.io.IOException; import org.apache.hadoop.ipc.ProtocolSignature; public class MyBusinessImpl implements MyBusiness{ @Override public ProtocolSignature getProtocolSignature(String arg0, long arg1, int arg2) throws IOException { //使用versionID创建签名 return new ProtocolSignature(versionID, null); } @Override public long getProtocolVersion(String arg0, long arg1) throws IOException { // 返回ID return versionID; } @Override public String sayHello(String name) { System.out.println("*****调用Server端的方法******"); //业务方法 return "Hello" + name; } }
5.MyRPCServer
package demo.proxy.rpc.server; import java.io.IOException; import org.apache.hadoop.HadoopIllegalArgumentException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.RPC; import org.apache.hadoop.ipc.RPC.Server; public class MyRPCServer { public static void main(String[] args) throws HadoopIllegalArgumentException, IOException { //ʹ创建一个RPC Server RPC.Builder builder = new RPC.Builder(new Configuration()); //指定Server的地址接口 builder.setBindAddress("localhost"); builder.setPort(7788); //发布程序 builder.setProtocol(MyBusiness.class);//定义的接口 builder.setInstance(new MyBusinessImpl());//发布的接口的实现 //创建RPC Server Server server = builder.build(); server.start(); } }
6.MyRPCClient
package demo.proxy.rpc.client; import java.net.InetSocketAddress; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.ipc.RPC; import demo.proxy.rpc.server.MyBusiness; public class MyRPCClient { public static void main(String[] args) throws Exception { //调用Server的功能 MyBusiness proxy = RPC.getProxy(MyBusiness.class,//调用的接口 MyBusiness.versionID,//版本的ID,必须跟服务器一致 new InetSocketAddress("localhost", 7788), //服务器的地址ַ new Configuration()); //调用服务器端的方法 System.out.println(proxy.sayHello("梦里南柯")); } }
先启动Server端,再启动Client端