1. 程式人生 > >自定義連線池

自定義連線池

 

package com.loaderman.demo.b_pool;

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.util.LinkedList;

/**
 * 自定義連線池, 管理連線
 * 程式碼實現:
 1.  MyPool.java  連線池類,
 2.  指定全域性引數:  初始化數目、最大連線數、當前連線、   連線池集合
 3.  建構函式:迴圈建立3個連線
 4.  寫一個建立連線的方法
 5.  獲取連線
 ------>  判斷: 池中有連線, 直接拿
 ------>                池中沒有連線,
 ------>                 判斷,是否達到最大連線數; 達到,丟擲異常;沒有達到最大連線數,
 建立新的連線
 6. 釋放連線
 ------->  連線放回集合中(..)
 *
 
*/ public class MyPool { private int init_count = 3; // 初始化連線數目 private int max_count = 6; // 最大連線數 private int current_count = 0; // 記錄當前使用連線數 // 連線池 (存放所有的初始化連線) private LinkedList<Connection> pool = new LinkedList<Connection>(); //1. 建構函式中,初始化連線放入連線池
public MyPool() { // 初始化連線 for (int i=0; i<init_count; i++){ // 記錄當前連線數目 current_count++; // 建立原始的連線物件 Connection con = createConnection(); // 把連線加入連線池 pool.addLast(con); } } //2. 建立一個新的連線的方法
private Connection createConnection(){ try { Class.forName("com.mysql.jdbc.Driver"); // 原始的目標物件 final Connection con = DriverManager.getConnection("jdbc:mysql:///jdbc_demo", "root", "root"); /**********對con物件代理**************/ // 對con建立其代理物件 Connection proxy = (Connection) Proxy.newProxyInstance( con.getClass().getClassLoader(), // 類載入器 //con.getClass().getInterfaces(), // 當目標物件是一個具體的類的時候 new Class[]{Connection.class}, // 目標物件實現的介面 new InvocationHandler() { // 當呼叫con物件方法的時候, 自動觸發事務處理器 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 方法返回值 Object result = null; // 當前執行的方法的方法名 String methodName = method.getName(); // 判斷當執行了close方法的時候,把連線放入連線池 if ("close".equals(methodName)) { System.out.println("begin:當前執行close方法開始!"); // 連線放入連線池 (判斷..) pool.addLast(con); System.out.println("end: 當前連線已經放入連線池了!"); } else { // 呼叫目標物件方法 result = method.invoke(con, args); } return result; } } ); return proxy; } catch (Exception e) { throw new RuntimeException(e); } } //3. 獲取連線 public Connection getConnection(){ // 3.1 判斷連線池中是否有連線, 如果有連線,就直接從連線池取出 if (pool.size() > 0){ return pool.removeFirst(); } // 3.2 連線池中沒有連線: 判斷,如果沒有達到最大連線數,建立; if (current_count < max_count) { // 記錄當前使用的連線數 current_count++; // 建立連線 return createConnection(); } // 3.3 如果當前已經達到最大連線數,丟擲異常 throw new RuntimeException("當前連線已經達到最大連線數目 !"); } //4. 釋放連線 public void realeaseConnection(Connection con) { // 4.1 判斷: 池的數目如果小於初始化連線,就放入池中 if (pool.size() < init_count){ pool.addLast(con); } else { try { // 4.2 關閉 current_count--; con.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } public static void main(String[] args) throws SQLException { MyPool pool = new MyPool(); System.out.println("當前連線: " + pool.current_count); // 3 // 使用連線 pool.getConnection(); pool.getConnection(); Connection con4 = pool.getConnection(); Connection con3 = pool.getConnection(); Connection con2 = pool.getConnection(); Connection con1 = pool.getConnection(); // 釋放連線, 連線放回連線池 // pool.realeaseConnection(con1); /* * 希望:當關閉連線的時候,要把連線放入連線池!【當呼叫Connection介面的close方法時候,希望觸發pool.addLast(con);操作】 * 把連線放入連線池 * 解決1:實現Connection介面,重寫close方法 * 解決2:動態代理 */ con1.close(); // 再獲取 pool.getConnection(); System.out.println("連線池:" + pool.pool.size()); // 0 System.out.println("當前連線: " + pool.current_count); // 3 } }