Java的代理对象实例

        Java的代理对象,可以通过代理来操作一个正真的实例对象,通过代理模式来重写那些我们需要增强的原对象的方法,下面是一个关于代理的简单实例:

1.定义一个接口类

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

2.实现上面接口的实现类

public class MyBusinessImpl implements MyBusiness {

	@Override
	public void method1() {
		// TODO Auto-generated method stub
		System.out.println("method1");
	}

	@Override
	public void method2() {
		// TODO Auto-generated method stub
		System.out.println("method2");
	}

}

3.通过一个代理对象重写原来对象的方法1

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

public class ProxyTestMain {
	public static void main(String[] args) {
		//创建真正的对象
		final MyBusiness obj = new MyBusinessImpl();
		
		//重写method1的实现---->不修改源码
		//生成真正的代理对象
		/*
		 Proxy.newProxyInstance(loader, 类加载器
		 						obj, 真正对象实现的接口
		 						arg2)InvocationHandler表示客户端如何调用代理对象
		  */
		MyBusiness proxyObj = (MyBusiness) Proxy.newProxyInstance(ProxyTestMain.class.getClassLoader(), 
							   obj.getClass().getInterfaces(), 
							   new InvocationHandler() {
								
								@Override
								public Object invoke(Object proxy, Method method, Object[] params)
										throws Throwable {
									//客户端的一次调用
									/*
									 * method: 客户端调用方法名
									 * params: 方法的参数
									 */
									if ("method1".equals(method.getName())) {
										System.out.println("********重写了method1***********");
										return null;
									}else {
										//不感兴趣的方法
										return method.invoke(obj, params);
									}
								}
							});
		proxyObj.method1();
		proxyObj.method2();
		
		
	}
}

4.以上代码就是一个简单的通过Java代理实现的重写原来对象的方法

5.我们可以通过代理对象实现一个简单的数据库连接池

(1)实现数据库连接池类

import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class MyDataSourcePool implements DataSource {

	//初始化连接池,放入10个连接
	private static String driver = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql://192.168.160.111:3306/hive";
	private static String user = "hiveowner";
	private static String password = "Welcome_1";
	
	//定义一个链表来保存10个连接
	private static LinkedList<Connection> dataSource = new LinkedList<>();
	static{
		try {
			//注册驱动
			Class.forName(driver);
			for (int i = 0; i < 5; i++) {
				dataSource.add(DriverManager.getConnection(url, user, password));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public Connection getConnection() throws SQLException {
		// 从连接池中返回该连接
		/*if (dataSource.size() > 0) {
			return dataSource.removeFirst();
		}else {
			throw new SQLException("系统繁忙,请稍后");
		}*/
		//代理获取连接
		//设置同步防止多线访问造成异常
		synchronized (dataSource) {
			if (dataSource.size() > 0) {
				final Connection connection = dataSource.removeFirst();
				Connection proxy = (Connection) Proxy.newProxyInstance(MyDataSourcePool.class.getClassLoader(), 
																connection.getClass().getInterfaces(), 
																new InvocationHandler() {
																	
																	@Override
																	public Object invoke(Object proxy, Method method, Object[] args)
																			throws Throwable {
																		// 重写close方法
																		if ("close".equals(method.getName())) {
																			dataSource.add(connection);
																			return null;
																		} else {
																			return method.invoke(connection, args);
																		}
																	}
																});
				return proxy;
			}else {
				throw new SQLException("系统繁忙,请稍后");
			}
		}
	}
	
	@Override
	public PrintWriter getLogWriter() throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setLogWriter(PrintWriter out) throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public void setLoginTimeout(int seconds) throws SQLException {
		// TODO Auto-generated method stub

	}

	@Override
	public int getLoginTimeout() throws SQLException {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Logger getParentLogger() throws SQLFeatureNotSupportedException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public <T> T unwrap(Class<T> iface) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean isWrapperFor(Class<?> iface) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Connection getConnection(String username, String password)
			throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

}

(2)测试连接池

import java.sql.Connection;

public class TestDataSourcePool {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		//从连接池中获取连接,使用完后释放连接
		MyDataSourcePool pool = new MyDataSourcePool();
		for (int i = 0; i < 11; i++) {
			Connection conn = pool.getConnection();
			System.out.println("第" + i + "个连接,是" + conn);
			conn.close();
		}
		
		//多线程访问数据库连接池
		Runnable runnable = new Runnable() {
			@Override
			public void run() {
				MyDataSourcePool pool = new MyDataSourcePool();
				for (int i = 0; i < 50; i++) {
					Connection conn = null;
					try {
						conn = pool.getConnection();
						System.out.println("第" + i + "个连接,是" + conn);
						conn.close();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						if (conn != null) {
							try {
								conn.close();
							} catch (SQLException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}
					
				}
			}
		};
		Thread t1 = new Thread(runnable);
		Thread t2 = new Thread(runnable);
		Thread t3 = new Thread(runnable);
		Thread t4 = new Thread(runnable);
		Thread t5 = new Thread(runnable);
		Thread t6 = new Thread(runnable);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		t6.start();
	}

}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值