廢話少說,直接上代碼!
package com.;
import javax.;
import java.lang.re;
import java.lang.re;
import java.lang.re;
import java.;
/**
* 對(duì)Connection對(duì)象的代理,主要作用為攔截connection的close方法
*/
public class ConnectionProxy implements InvocationHandler {
//真實(shí)的連接
private Connection realConnection ;
//代理的連接
private Connection proxyConnection ;
//數(shù)據(jù)源
private HuwcDataSource dataSource ;
//這是一個(gè)構(gòu)造器
public ConnectionProxy(Connection realConnection, HuwcDataSource dataSource) {
= realConnection;
= dataSource;
//生成代理的Connection
= (Connection) Proxy.newProxyInstance(), new Class[]{Connec}, this);
}
public Connection getRealConnection() {
return realConnection;
}
public void setRealConnection(Connection realConnection) {
= realConnection;
}
public Connection getProxyConnection() {
return proxyConnection;
}
public void setProxyConnection(Connection proxyConnection) {
= proxyConnection;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(HuwcDataSource dataSource) {
= dataSource;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = me();
//攔截連接關(guān)閉的方法,對(duì)其進(jìn)行擴(kuò)展處理
i("close")){
synchronized ()){
//活動(dòng)連接list中remove這個(gè)ConnectionProxy
da().remove(this);
//如果空閑連接list中的數(shù)量沒有達(dá)到閾值,則裝入空間連接list,并notifyAll
i().size() < da()){
da().add(this);
da().notifyAll();
}else{
//否則,直接關(guān)閉這個(gè)Connection
realConnec();
}
}
}else{
return me(realConnection, args) ;
}
return null;
}
}
package com.;
import javax.;
import java.io.PrintWriter;
import java.;
import java.;
import java.u;
/**
* 給與DataSource接口中一些方法默認(rèn)實(shí)現(xiàn)(就是不實(shí)現(xiàn))
*/
public abstract class HuwcAbstractDataSource implements DataSource {
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
public PrintWriter getLogWriter() throws SQLException {
return null;
}
public void setLogWriter(PrintWriter out) throws SQLException {
}
public void setLoginTimeout(int seconds) throws SQLException {
}
public int getLoginTimeout() throws SQLException {
return 0;
}
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
package com.;
import java.;
import java.;
import java.;
import java.u;
import java.u;
public class HuwcDataSource extends HuwcAbstractDataSource {
//空閑的連接
private List<ConnectionProxy> idleConnections = new ArrayList<>();
//活動(dòng)的連接
private List<ConnectionProxy> activeConnections = new ArrayList<>();
//是否為本數(shù)據(jù)源第一次獲取連接標(biāo)志
private boolean firstFlag = true ;
//最小的空閑連接數(shù)
private Integer minIdleConnectionsCount = 2;
//最大的空閑連接數(shù)
private Integer maxIdleConnectionsCount = 5;
//最大的活動(dòng)連接數(shù)
private Integer maxActiveConnectionsCount = 10;
//獲取連接的最大的等待時(shí)間(毫秒)
private Integer maxWaitToTimeOut = 30000;
private String url;
private String driver;
private String user;
private String password;
private Object monitor = new Object();
public boolean isFirstFlag() {
return firstFlag;
}
public void setFirstFlag(boolean firstFlag) {
= firstFlag;
}
public List<ConnectionProxy> getIdleConnections() {
return idleConnections;
}
public void setIdleConnections(List<ConnectionProxy> idleConnections) {
= idleConnections;
}
public List<ConnectionProxy> getActiveConnections() {
return activeConnections;
}
public void setActiveConnections(List<ConnectionProxy> activeConnections) {
= activeConnections;
}
public Integer getMaxIdleConnectionsCount() {
return maxIdleConnectionsCount;
}
public void setMaxIdleConnectionsCount(Integer maxIdleConnectionsCount) {
= maxIdleConnectionsCount;
}
public Integer getMaxActiveConnectionsCount() {
return maxActiveConnectionsCount;
}
public void setMaxActiveConnectionsCount(Integer maxActiveConnectionsCount) {
= maxActiveConnectionsCount;
}
public Integer getMaxWaitToTimeOut() {
return maxWaitToTimeOut;
}
public void setMaxWaitToTimeOut(Integer maxWaitToTimeOut) {
= maxWaitToTimeOut;
}
public Object getMonitor() {
return monitor;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
= url;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
= driver;
}
public String getUser() {
return user;
}
public void setUser(String user) {
= user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
= password;
}
@Override
public Connection getConnection() throws SQLException {
return getConnection(user, password);
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return doGetConnection(username, password);
}
private Connection doGetConnection(String username, String password) throws SQLException {
while(true) {
synchronized (monitor) {
//如果是本數(shù)據(jù)源第一次獲取連接,那么首先進(jìn)行init操作
if(firstFlag)
init();
//首先從空閑連接list中獲取
if () > 0) {
return idleConnec(0).getProxyConnection();
} else {//空閑連接list中如果沒有連接的情況
//如果活動(dòng)連接list的數(shù)量還沒有達(dá)到閾值
if (maxActiveConnectionsCount > ac()) {
//獲取一個(gè)真實(shí)的Connection,并且封裝為ConnectionProxy,裝入活動(dòng)連接list
ConnectionProxy connectionProxy = new ConnectionProxy(url, user, password), this);
ac(connectionProxy);
return connec();
} else {
//如果活動(dòng)連接list的數(shù)量已經(jīng)達(dá)到了閾值
//等待超時(shí)時(shí)間,并等待被喚醒
try {
moni(maxWaitToTimeOut);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
}
return null ;
}
private void init() {
//首先進(jìn)行鎖定處理
firstFlag = false;
for(int i=0;i<minIdleConnectionsCount;i++){
try {
ConnectionProxy connectionProxy = new ConnectionProxy(url, user, password), this);
.add(connectionProxy);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
總結(jié):
通過jdk動(dòng)態(tài)代理,給Connection對(duì)象生成一個(gè)代理對(duì)象,主要目的為攔截connection的close方法,不要直接進(jìn)行connection的關(guān)閉,而是在DataSource中的活動(dòng)連接集合和空閑連接集合進(jìn)行轉(zhuǎn)換。真實(shí)的Connection依然是通過DirverManager類來(lái)創(chuàng)建。
原文鏈接:
1.《.net如何連接數(shù)據(jù)庫(kù)連接池看這里!手寫數(shù)據(jù)庫(kù)連接池你還不會(huì)?廢話少說,直接上代碼》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。
2.《.net如何連接數(shù)據(jù)庫(kù)連接池看這里!手寫數(shù)據(jù)庫(kù)連接池你還不會(huì)?廢話少說,直接上代碼》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。
3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/gl/2174575.html