Proxool连接池解析(中)


三  代码解读

    1.  连接池管理

    先看如何获取到数据库连接, 以此为入口。 在 ProxoolDataSource 中:

public Connection getConnection() throws SQLException {
        ConnectionPool cp = null;
        try {
            if (!ConnectionPoolManager.getInstance().isPoolExists(alias)) {
                registerPool();
            }
            cp = ConnectionPoolManager.getInstance().getConnectionPool(alias);
            return cp.getConnection();
        } catch (ProxoolException e) {
            LOG.error("Problem gettingconnection", e);
            throw new SQLException(e.toString());
        }
}

根据 ProxoolDataSource 的 alias 属性先到连接池管理处查询是否已经有对应的连接池,如果没有,则注册相应的连接池, 如果有,则获取Connection 对象。 注册连接池的代码如下:

private synchronized void registerPool()throwsProxoolException {
        if (!ConnectionPoolManager.getInstance().isPoolExists(alias)) {
            ConnectionPoolDefinition cpd = newConnectionPoolDefinition();
            cpd.setAlias(getAlias());
            cpd.setDriver(getDriver());
            // cpd.setXXX(getXXX()); // 设置各种属性
            // We must setUser and setPassword*after* setDelegateProperties
            // otherwise the values will beoverwritten. Credit Bulent Erdemir.
            cpd.setUser(getUser());
            cpd.setPassword(getPassword());
            ProxoolFacade.registerConnectionPool(cpd);
        }
}

ConnectionPoolManager有一个 connectionPoolMap 对象, 存储从 alias 到 ConnectionPool 的映射。 可见 alias 的重要性。 获取ProxoolDataSource对应的连接池的代码:

protected ConnectionPoolgetConnectionPool(String alias) throws ProxoolException {
        ConnectionPool cp = (ConnectionPool) connectionPoolMap.get(alias);
        if (cp == null) {
            throw newProxoolException(getKnownPools(alias));
        }
        return cp;
}

这是创建连接池的代码:

protected ConnectionPoolcreateConnectionPool(ConnectionPoolDefinition connectionPoolDefinition) throwsProxoolException {
        ConnectionPool connectionPool = newConnectionPool(connectionPoolDefinition);
        connectionPools.add(connectionPool);
        connectionPoolMap.put(connectionPoolDefinition.getAlias(),connectionPool);
        return connectionPool;
}

      事实上,ConnectionPoolManager 并没有做太多事情, 主要是管理ProxoolDataSource(alias)到相应ConnectionPool的映射关系。ProxoolFacade用于管理连接池的注册、移除及监听事件。注册连接池的主要工作:首先,在 ConnectionPoolManager中创建该连接池并添加映射, 接着启动该连接池的任务, 以及监听器的注册处理程序,最后处理 JDNI 及 JMX 相关。

protected synchronized static voidregisterConnectionPool(ConnectionPoolDefinition connectionPoolDefinition) throwsProxoolException {
        // check isPoolExists once morenow we are inside synchronized block.
        if (!ConnectionPoolManager.getInstance().isPoolExists(connectionPoolDefinition.getAlias())){
            Properties jndiProperties = extractJndiProperties(connectionPoolDefinition);
            ConnectionPool connectionPool =ConnectionPoolManager.getInstance().createConnectionPool(connectionPoolDefinition);
            connectionPool.start();
            compositeProxoolListener.onRegistration(connectionPoolDefinition,connectionPoolDefinition.getCompleteInfo());
            if (isConfiguredForJMX(connectionPoolDefinition.getCompleteInfo())){
                registerForJmx(connectionPoolDefinition.getAlias(),connectionPoolDefinition.getCompleteInfo());
            }
            if (jndiProperties != null) {
                registerDataSource(connectionPoolDefinition.getAlias(),jndiProperties);
            }
        } else {
            LOG.debug("Ignoring duplicate attemptto register " + connectionPoolDefinition.getAlias()+ "pool");
        }
    } 

连接池启动任务代码如下:

/** Starts up house keeping andprototyper threads. */
    protected void start() throwsProxoolException {
        connectionPoolUp = true;
        prototyper = new Prototyper(this);
        HouseKeeperController.register(this);
}
 
/**
     * Schedule a regular triggerSweep
     * @param connectionPool  identifies the pool
     */
    protected static void register(ConnectionPoolconnectionPool) {
        String alias =connectionPool.getDefinition().getAlias();
        LOG.debug("Registering '" + alias + "' housekeeper");
        HouseKeeper houseKeeper = newHouseKeeper(connectionPool);
        synchronized (LOCK) {
            houseKeepers.put(alias,houseKeeper);
            houseKeeperList.add(houseKeeper);
 
            if (houseKeeperThreads.size() == 0) {
                HouseKeeperThread hkt = newHouseKeeperThread("HouseKeeper");
                LOG.debug("Starting a house keeperthread");
                hkt.start();
                houseKeeperThreads.add(hkt);
            }
        }
}

后面再来看这个 houseKeeperThread 的任务内容。 这里暂时搁下。

 

2.  数据库连接管理

   现在来看如何在连接池中获取数据库连接。 在 ConnectionPool 中,获取数据库连接的代码如下:   

/**
     * Get a connection from 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值