Java的动态代理

  • java的动态对象是编程模式的装饰者模式
  • 可以通过包装的方式,让函数完成不同的功能
    原理

1.java代码实例

1).创建服务端接口MyServer.java,创建方法method1method2

public interface MyServer{
    public void method1();
    public void method2();
}

2).创建实现接口方法的Class MyServerImp.java文件

public class MyServerImp implements MyServer{
        @Override
        public void method1(){
            System.out.println("**** method1 ****");
        }
        @Override
        public void method2(){
            System.out.println("**** method2 ***");
        }
    }

3).创建个Demo类TestProxy.java,来实现代理

//1.导入Proxy类相关的组件
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.relect.Proxy;

//创建类
public class TestProxy{
    public static void main(String[] args){
        //创建实例
        final MyServer obj = new MyServerImp();
        //创建代理对象
        MyServer proxy = Proxy.newProxyInstance(TestProxy.class.getClassLoader(),
        obj.getClass.getInterfaces(),
        new InvocationHandler(){
            @Override
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               if(method.getName().equals("method1")){
                   System.out.println(**proxy method1***);
                   return null;
               }else{
                   method.invoke(obj,args);
               }
               return null;
           }
        });
        
        
        //执行方法
        proxy.method1();
        proxy.method2();
        
    }
}

1.java的JDBC数据库连接池代理

JBDC原理 

1.导入Mysql的jar包mysql-connector-java-5.1.44-bin.jar官网下载
2.新建package data.datasource 3.新建类MyDataSourcePool.java实现DataSource.java接口(java.sql)
4.初始化连接池,

//创建Mysql驱动
private static String driver = "com.mysql.jdbc.Driver";
//创建Mysql连接
private static String url = "jabc:mysql://192.168.142.111:3306/hive";
//Mysql的用户
pravate static String user = "hiveowner";
//Mysql的密码
private static String password = "Welcome_1";
//定义一个连接链表
private static LinkList<Connection>dataSource = new LinkedList<>)();
//连接数据库驱动

static{
    try{
//(java的反射方式)注册数据仓库
        Class.forName(driver);
//创建10个连接
        for(int i=0;i<10;i++){
            dataSource.add(DriveManager.getConnection(url,user,password));
        }
    }catch(Exception ex){
        ex.printStackTrace();
    }
}
//不通过代理,直接返回连接给客户端
@Override
public Connection getConnection() throw Exception{
if dataSource.size()>0{
    final Connection conn = dataSource.removeFirst();
    Connection proxyConn = (Connection)Proxy.newProxyInstance( MyDataSourcePool.class.getClassLoader(),
			conn.getClass().getInterfaces(),
			new InvocationHandler() {
				
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//重写close方法
		if(method.getName().equals("close")){
			dataSource.add(conn);
			return null;
		}else{
			//调用了其他方法
			return method.invoke(conn, args);
		}
		
	}
}); 
	
	return proxyConn;
    }else
    {
        throw new SQLException("系统繁忙情稍后重试");
    }
}

5.新建TestDataSource.java来测试连接

public static void main(String[] args) throw Exception{
    MyDataSourcePool ds = new MyDataSourcePool();
    //取出连接使用
    for(int i=0;i<12;i++){
        Connection conn = ds.getConnection();
        System.out.println("第"+i+"个连接"+conn);
        conn.close();
    }
}

6.返回结果

第0个连接 :com.mysql.jdbc.JDBC4Connection@3a883ce7
第1个连接 :com.mysql.jdbc.JDBC4Connection@4973813a
第2个连接 :com.mysql.jdbc.JDBC4Connection@6321e813
第3个连接 :com.mysql.jdbc.JDBC4Connection@79be0360
第4个连接 :com.mysql.jdbc.JDBC4Connection@22a67b4
第5个连接 :com.mysql.jdbc.JDBC4Connection@57855c9a
第6个连接 :com.mysql.jdbc.JDBC4Connection@3b084709
第7个连接 :com.mysql.jdbc.JDBC4Connection@3224f60b
第8个连接 :com.mysql.jdbc.JDBC4Connection@63e2203c
第9个连接 :com.mysql.jdbc.JDBC4Connection@1efed156
第10个连接 :com.mysql.jdbc.JDBC4Connection@3a883ce7
第11个连接 :com.mysql.jdbc.JDBC4Connection@4973813a

RPC协议的代理

全称:远程过程调用(remote procedure call)

Hadoop实现了RPC协议

Server

Client

RPC原理 

RPC的Server
1.定义接口MyBusiness.java来继承父接口VersionedProtocol

public interface MyBusiness extends VersionedProtocol {
	//定义自己的 签名 ID号,通过ID号,区分在客户端调用的时候是调用的是哪个具体的实现
	//变量的名字必须交VersionID
	public static long versionID = 11;
	//定义一个自己的方法
	public String SayHello(String name);
}

2.创建类MyBusinessImp.java实现接口MyBusiness.java的方法

public class MyBusinessImp implements MyBusiness {
	//定义自己的 签名 ID号,通过ID号,区分在客户端调用的时候是调用的是哪个具体的实现
	//变量的名字必须交VersionID
	
	@Override
	public ProtocolSignature getProtocolSignature(String arg0, long arg1, int arg2) throws IOException {
		// 返回签名
		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;
	}

}

3.创建类MyRPCServer.java,部署服务端程序,例如JSP部署到Tomcat

包环境

package demo.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 static void main(String[] args) throws HadoopIllegalArgumentException, IOException {
	// 使用HDFS的RPC Server来部署我们的程序
	RPC.Builder builder = new RPC.Builder(new Configuration());
	//设置主机信息
	builder.setBindAddress("localhost");
	//设置端口信息
	builder.setPort(7788);
	
	//部署我们的程序
	builder.setProtocol(MyBusiness.class);//部署接口
	builder.setInstance(new MyBusinessImp());//调用客户端,需要指定相同的签名
	
	//生成RPC Server
	Server server = builder.build();
	server.start();
	

}

RPC的Client
1.创建MyRPCClient.java,来创建我们的客户端
创建RPC的客户端,通过这个客户端去调用RPC

import java.io.IOException;
 import java.net.InetSocketAddress;import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.ipc.RPC;import demo.rpc.server.MyBusiness;
public static void main(String[] args) throws IOException {
	// TODO Auto-generated method stub
	MyBusiness proxy = RPC.getProxy(MyBusiness.class, // 调用的借口
				 MyBusiness.versionID, //签名信息
				 new InetSocketAddress("localhost", 7788), //服务器地址
				 new Configuration());//配置信息
	System.out.println(proxy.SayHello("Tom"));
}