- druid1.2.8源码阅读:第二天
- 一、问题
- 二、当`new DruidDataSource()`时,在执行什么
- 2.1 调用父类`DruidAbstractDataSource`的构造函数
- 2.2 初始化`DruidDataSource`中的参数
- 2.3 读取系统配置
我在想如果我要开发一个数据源连接池,我会怎么做。简单的JDBC要经历如下步骤:
- 第一步:加载数据库驱动;
- 第二步:建立数据库连接;
- 第三步:通过Statement执行SQL;
- 第四步:从RestSet中获取返回结果;
首先,初始化参数
// 默认参数 // 默认自定提交打开 protected volatile boolean defaultAutoCommit = true; // 初始化大小为0 protected volatile int initialSize = DEFAULT_INITIAL_SIZE; // 最大活跃数位0 protected volatile int maxActive = DEFAULT_MAX_ACTIVE_SIZE; // 最小空闲连接数 0 protected volatile int minIdle = DEFAULT_MIN_IDLE; // 最大空闲连接数 8 protected volatile int maxIdle = DEFAULT_MAX_IDLE; // 最大等待毫秒数:-1,无限长。超过这个时间就报错 protected volatile long maxWait = DEFAULT_MAX_WAIT; // 拿链接失败重试的次数 protected int notFullTimeoutRetryCount = 0; // 用于验证的查询语句:默认为null protected volatile String validationQuery = DEFAULT_VALIDATION_QUERY; // 验证语句查询超时时间:默认无限长 protected volatile int validationQueryTimeout = -1; // 从连接池获取申请链接时,连接池判断这连接是否是可用的。默认为false protected volatile boolean testOnBorrow = DEFAULT_TEST_ON_BORROW; // 使用完连接,连接池回收的时候判断该连接是否可用。默认为false protected volatile boolean testOnReturn = DEFAULT_TEST_ON_RETURN; // 从连接池申请连接时,如果testOnBorrow=false,验证是否为空闲连接,如果是验证连接是否可用。默认为false protected volatile boolean testWhileIdle = DEFAULT_WHILE_IDLE; // 是否缓存游标,对支持游标的数据库性能提升巨大。默认为false protected volatile boolean poolPreparedStatements = false; // 是否缓存preparedStatement, 也就是PSCache,默认为false protected volatile boolean sharePreparedStatements = false; // 每个连接上PSCache的大小 protected volatile int maxPoolPreparedStatementPerConnectionSize = 10; // protected volatile boolean inited = false; // protected volatile boolean initExceptionThrow = true; private boolean clearFiltersEnable = true; // 驱动 protected Driver driver; // 执行查询的超时时间(秒) protected volatile int queryTimeout; // 执行一个事务的超时时间(秒) protected volatile int transactionQueryTimeout; // protected long createTimespan; // 最大等待线程,默认不限个数 protected volatile int maxWaitThreadCount = -1; // protected volatile boolean accessToUnderlyingConnectionAllowed = true; // 作为DestroyTask执行的时间周期, 默认60s。如果连接数大于minIdle,则关闭多余的,如果小于minIdle,则创建 protected volatile long timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS; // 每次检查多少个连接 protected volatile int numTestsPerEvictionRun = DEFAULT_NUM_TESTS_PER_EVICTION_RUN; // 空闲线程逐出线程池时间,默认30分钟 protected volatile long minEvictableIdleTimeMillis = DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS; // 当连接池中连接个数小于minIdle,这些线程空闲多久关闭。默认7小时 protected volatile long maxEvictableIdleTimeMillis = DEFAULT_MAX_EVICTABLE_IDLE_TIME_MILLIS; // 当连接的空闲时间大于keepAliveBetweenTimeMillis(默认2分钟),但是小于minEvictableIdleTimeMillis(默认30分钟),Druid会通过调用validationQuery保持该连接的有效性。 //当连接空闲时间大于minEvictableIdleTimeMillis,Druid会直接将该连接关闭,keepAlive会无效。 protected volatile long keepAliveBetweenTimeMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS * 2; // 物理连接超时时间,默认-1 protected volatile long phyTimeoutMillis = DEFAULT_PHY_TIMEOUT_MILLIS; // 物理连接最大使用数量 protected volatile long phyMaxUseCount = -1; // 如果连接泄露,是否需要回收泄露的连接,默认false; protected volatile boolean removeAbandoned; // 连接回收的超时时间,默认5分钟 protected volatile long removeAbandonedTimeoutMillis = 300 * 1000; // 如果回收了泄露的连接,是否要打印一条log,默认false; protected volatile boolean logAbandoned; // 连接建立后,初始化SQL protected volatile ListconnectionInitSqls; // 数据库类型 protected volatile String dbTypeName; // 连接出错后重试时间间隔,默认500毫秒 protected volatile long timeBetweenConnectErrorMillis = DEFAULT_TIME_BETWEEN_CONNECT_ERROR_MILLIS; // protected volatile ValidConnectionChecker validConnectionChecker = null; // 活跃连接 protected final Map activeConnections = new IdentityHashMap (); // 设置获取连接出错时的自动重连次数 protected int connectionErrorRetryAttempts = 1; // true表示向数据库请求连接失败后,就算后端数据库恢复正常也不进行重连,客户端对pool的请求都拒绝掉.false表示新的请求都会尝试去数据库请求connection.默认为false protected boolean breakAfterAcquireFailure = false; // 启用异步关闭连接 private boolean asyncCloseConnectionEnable = false; // 配置了timeBetweenLogStatsMillis属性(大于0)之后,就会定时输出统计信息到日志中。每次输出日志会导致清零(reset)连接池相关的计数器。 protected long timeBetweenLogStatsMillis;
// 默认创建一个 非公平的锁: 不保证先来的线程先得到锁 protected ReentrantLock lock = new ReentrantLock(lockFair); protected Condition notEmpty = lock.newCondition(); protected Condition empty = lock.newCondition();2.2 初始化DruidDataSource中的参数
// 保持连接的有效性,也就是跟数据库续租; // 当连接的空闲时间大于keepAliveBetweenTimeMillis(默认2分钟),但是小于minEvictableIdleTimeMillis(默认30分钟),Druid会通过调用validationQuery保持该连接的有效性。 private volatile boolean keepAlive = false; // 可通过 loadSpifilterSkip 属性配置是否跳过通过spi机制加载的Filter private boolean loadSpifilterSkip = false; // 合并多个DruidDataSource的监控数据 private boolean useGlobalDataSourceStat = false;2.3 读取系统配置
读取系统配置:
- druid.name
- druid.url
- druid.username
- druid.password
- druid.testWhileIdle
- druid.testOnBorrow
- druid.validationQuery
- druid.useGlobalDataSourceStat
- druid.useGloalDataSourceStat 兼容早期版本
- druid.asyncInit 兼容早起版本, 是否进行异步初始化
- druid.filters
- druid.timeBetweenLogStatsMillis
- druid.stat.sql.MaxSize 控制Map容量
- druid.clearFiltersEnable 是否允许清除过滤器
- druid.resetStatEnable 是否允许重置状态
- druid.notFullTimeoutRetryCount
- druid.timeBetweenEvictionRunsMillis
- druid.maxWaitThreadCount
- druid.maxWait
- druid.failFast 是否快速失败
- druid.phyTimeoutMillis
- druid.phyMaxUseCount
- druid.minEvictableIdleTimeMillis
- druid.keepAlive
- druid.keepAliveBetweenTimeMillis
- druid.poolPreparedStatements
- druid.initVariants
- druid.initGlobalVariants
- druid.useUnfairLock
- druid.driverClassName
- druid.initialSize
- druid.minIdle
- druid.maxActive
- druid.killWhenSocketReadTimeout
- druid.connectProperties
- druid.maxPoolPreparedStatementPerConnectionSize
- druid.initConnectionSqls
- druid.load.spifilter.skip
- druid.checkExecuteTime
configFromPropety(System.getProperties());



