源码解析之datasource连接池创建连接方式

一.连接池采用的创建连接方式

1.1 POOLED(集合,重复):

采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现

使用了连接池技术,不会安抚创建和销毁连接

1.1.1 如何查看pooled监听方式日志

在这里插入图片描述

1.1.2 源码分析

第一步进入 PooledDataSource,的396行看到这个方法

 while (conn == null) {
      synchronized (state) {
        if (!state.idleConnections.isEmpty()) {
          // Pool has available connection
          conn = state.idleConnections.remove(0);
          if (log.isDebugEnabled()) {
            log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");
          }
        } else {

说明了

说明他通过调用idleConnections.remove(0)去删除连接

第二步进入 idleConnections

//看到List集合就很清楚的明白POOLED的理念是通过集合存储
protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>();
  protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>();

1.2 UNPOOLED(数组,不重复):

采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的

思想。

与上面相反,没有采用连接池技术,会反复的创建和销毁连接,利用数组存储

在这里插入图片描述

1.2.1 来查看源码

1.2.1.1

在这里插入图片描述

进入了UnpooledDataSource,映入眼帘的是一堆的方法

public class UnpooledDataSource implements DataSource {
    private ClassLoader driverClassLoader;
    private Properties driverProperties;
    private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap();
    private String driver;
    private String url;
    private String username;
    private String password;
    private Boolean autoCommit;
    private Integer defaultTransactionIsolationLevel;

    public UnpooledDataSource() {
    }

    public UnpooledDataSource(String driver, String url, String username, String password) {
        this.driver = driver;
        this.url = url;
        this.username = username;
        this.password = password;
    }

    public UnpooledDataSource(String driver, String url, Properties driverProperties) {
        this.driver = driver;
        this.url = url;
        this.driverProperties = driverProperties;
    }

    public UnpooledDataSource(ClassLoader driverClassLoader, String driver, String url, String username, String password) {
        this.driverClassLoader = driverClassLoader;
        this.driver = driver;
        this.url = url;
        this.username = username;
        this.password = password;
    }

    public UnpooledDataSource(ClassLoader driverClassLoader, String driver, String url, Properties driverProperties) {
        this.driverClassLoader = driverClassLoader;
        this.driver = driver;
        this.url = url;
        this.driverProperties = driverProperties;
    }

    public Connection getConnection() throws SQLException {
        return this.doGetConnection(this.username, this.password);
    }

    public Connection getConnection(String username, String password) throws SQLException {
        return this.doGetConnection(username, password);
    }

    public void setLoginTimeout(int loginTimeout) throws SQLException {
        DriverManager.setLoginTimeout(loginTimeout);
    }

    public int getLoginTimeout() throws SQLException {
        return DriverManager.getLoginTimeout();
    }

    public void setLogWriter(PrintWriter logWriter) throws SQLException {
        DriverManager.setLogWriter(logWriter);
    }

    public PrintWriter getLogWriter() throws SQLException {
        return DriverManager.getLogWriter();
    }

    public ClassLoader getDriverClassLoader() {
        return this.driverClassLoader;
    }

    public void setDriverClassLoader(ClassLoader driverClassLoader) {
        this.driverClassLoader = driverClassLoader;
    }

    public Properties getDriverProperties() {
        return this.driverProperties;
    }

    public void setDriverProperties(Properties driverProperties) {
        this.driverProperties = driverProperties;
    }

    public String getDriver() {
        return this.driver;
    }

    public synchronized void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Boolean isAutoCommit() {
        return this.autoCommit;
    }

    public void setAutoCommit(Boolean autoCommit) {
        this.autoCommit = autoCommit;
    }

    public Integer getDefaultTransactionIsolationLevel() {
        return this.defaultTransactionIsolationLevel;
    }

    public void setDefaultTransactionIsolationLevel(Integer defaultTransactionIsolationLevel) {
        this.defaultTransactionIsolationLevel = defaultTransactionIsolationLevel;
    }

    private Connection doGetConnection(String username, String password) throws SQLException {
        Properties props = new Properties();
        if (this.driverProperties != null) {
            props.putAll(this.driverProperties);
        }

        if (username != null) {
            props.setProperty("user", username);
        }

        if (password != null) {
            props.setProperty("password", password);
        }

        return this.doGetConnection(props);
    }

    private Connection doGetConnection(Properties properties) throws SQLException {
        this.initializeDriver();
        Connection connection = DriverManager.getConnection(this.url, properties);
        this.configureConnection(connection);
        return connection;
    }

    private synchronized void initializeDriver() throws SQLException {
        if (!registeredDrivers.containsKey(this.driver)) {
            try {
                Class driverType;
                if (this.driverClassLoader != null) {
                    driverType = Class.forName(this.driver, true, this.driverClassLoader);
                } else {
                    driverType = Resources.classForName(this.driver);
                }

                Driver driverInstance = (Driver)driverType.newInstance();
                DriverManager.registerDriver(new UnpooledDataSource.DriverProxy(driverInstance));
                registeredDrivers.put(this.driver, driverInstance);
            } catch (Exception var3) {
                throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + var3);
            }
        }

    }

    private void configureConnection(Connection conn) throws SQLException {
        if (this.autoCommit != null && this.autoCommit != conn.getAutoCommit()) {
            conn.setAutoCommit(this.autoCommit);
        }

        if (this.defaultTransactionIsolationLevel != null) {
            conn.setTransactionIsolation(this.defaultTransactionIsolationLevel);
        }

    }

    public <T> T unwrap(Class<T> iface) throws SQLException {
        throw new SQLException(this.getClass().getName() + " is not a wrapper.");
    }

    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    public Logger getParentLogger() {
        return Logger.getLogger("global");
    }

    static {
        Enumeration drivers = DriverManager.getDrivers();

        while(drivers.hasMoreElements()) {
            Driver driver = (Driver)drivers.nextElement();
            registeredDrivers.put(driver.getClass().getName(), driver);
        }

    }

    private static class DriverProxy implements Driver {
        private Driver driver;

        DriverProxy(Driver d) {
            this.driver = d;
        }

        public boolean acceptsURL(String u) throws SQLException {
            return this.driver.acceptsURL(u);
        }

        public Connection connect(String u, Properties p) throws SQLException {
            return this.driver.connect(u, p);
        }

        public int getMajorVersion() {
            return this.driver.getMajorVersion();
        }

        public int getMinorVersion() {
            return this.driver.getMinorVersion();
        }

        public DriverPropertyInfo[] getPropertyInfo(String u, Properties p) throws SQLException {
            return this.driver.getPropertyInfo(u, p);
        }

        public boolean jdbcCompliant() {
            return this.driver.jdbcCompliant();
        }

        public Logger getParentLogger() {
            return Logger.getLogger("global");
        }
    }
}
1.2.1.2 去找UnPooledDataSource中获取连接的地方(即方法开始的地方)

进入doGetConnection方法

 private Connection doGetConnection(String username, String password) throws SQLException {
        Properties props = new Properties();
        if (this.driverProperties != null) {
            props.putAll(this.driverProperties);
        }

        if (username != null) {
            props.setProperty("user", username);
        }

        if (password != null) {
            props.setProperty("password", password);
        }
//发现他下面又调用了一个doGetConnection,进入此方法
        return this.doGetConnection(props);
    }
1.2.1.3 发现上一个doGetConnection又调用了一个doGetConnection,进入此doGetConnection方法
   private Connection doGetConnection(Properties properties) throws SQLException {
        this.initializeDriver();
        
        //创建连接
        Connection connection = DriverManager.getConnection(this.url, properties);
        this.configureConnection(connection);
        return connection;
    }

1.2.14 进入initializeDriver

private synchronized void initializeDriver() throws SQLException {
    if (!registeredDrivers.containsKey(driver)) {
      Class<?> driverType;
      try {
        if (driverClassLoader != null) {
       //Class.forName通过反射加载驱动
       driverType = Class.forName(driver, true, driverClassLoader);
        } else {
          driverType = Resources.classForName(driver);
        }
        // DriverManager requires the driver to be loaded via the system ClassLoader.
        // http://www.kfu.com/~nsayer/Java/dyn-jdbc.html
        Driver driverInstance = (Driver)driverType.newInstance();
        DriverManager.registerDriver(new DriverProxy(driverInstance));
        registeredDrivers.put(driver, driverInstance);
      } catch (Exception e) {
        throw new SQLException("Error setting driver on UnpooledDataSource. Cause: " + e);
      }
    }
  }

说明了

第一点:

//1.Class.forName通过反射加载驱动
       driverType = Class.forName(driver, true, driverClassLoader);
       说明UNPOOLED每次都是通过反射去加载驱动的,
 

进一步明确了

第二点:

 就可以说明UNPOOLED每次都是通过1.2.1.3的doGetConnection方法的 
 DriverManager去加载驱动获取新的连接
 
 //创建连接
        Connection connection = DriverManager.getConnection(this.url, properties);

分析出:

第三点:

因为每次都是穿建新的连接,所以UNPOOLED一定是用数组存储的。

1.3JNDI:

采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是

不一样。

注意:如果不是web或者maven的war工程,JNDI是不能使用的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值