写点什么

数据库连接池 -Druid 源码学习(二)

作者:wjchenge
  • 2022 年 5 月 11 日
  • 本文字数:1336 字

    阅读完需:约 4 分钟

1、简介

在本文中,我们将深入了解 com.alibaba.druid.pool.DruidDataSource#init 方法的执行流程的几个细节。

2、环境

os-window10druid-1.2.8jdk-1.8.0_312maven-3.8.1
复制代码

3、初始化代码的几处细节

1、jdbcUrl、driverClass 进行了前后去空格处理

if (this.jdbcUrl != null) {  this.jdbcUrl = this.jdbcUrl.trim();  initFromWrapDriverUrl();}
复制代码


if (this.driverClass != null) {  this.driverClass = driverClass.trim();}
复制代码

2、com.alibaba.druid.pool.DruidDataSource#initFromWrapDriverUrl 只处理数据库连接以 jdbc:wrap-jdbc:开头的情况

public final static String DEFAULT_PREFIX = "jdbc:wrap-jdbc:";
...... if (!jdbcUrl.startsWith(DruidDriver.DEFAULT_PREFIX)) { return;}
复制代码

3、只执行了 Filter 的 init()方法

for (Filter filter : filters) {  filter.init(this);}
复制代码

4、通过 spi 机制加载用户自定义的 Filter

private void initFromSPIServiceLoader() {  // 可通过 loadSpifilterSkip 属性配置是否跳过通过spi机制加载的Filter  // 该方式可全量跳过不加载  if (loadSpifilterSkip) {    return;  }
if (autoFilters == null) { List<Filter> filters = new ArrayList<Filter>(); ServiceLoader<Filter> autoFilterLoader = ServiceLoader.load(Filter.class);
// 通过 AutoLoad 注解控制需要通过spi机制加载的Filter // 该方式可按需选择加载 for (Filter filter : autoFilterLoader) { AutoLoad autoLoad = filter.getClass().getAnnotation(AutoLoad.class); if (autoLoad != null && autoLoad.value()) { filters.add(filter); } } autoFilters = filters; }
for (Filter filter : autoFilters) { if (LOG.isInfoEnabled()) { LOG.info("load filter from spi :" + filter.getClass().getName()); } // 会做去重处理,并执行init()方法,然后放入 filters 集合 addFilter(filter); }}
复制代码


/** * 会去重复 *  * @param filter */private void addFilter(Filter filter) {  boolean exists = false;  for (Filter initedFilter : this.filters) {    if (initedFilter.getClass() == filter.getClass()) {      exists = true;      break;    }  }
if (!exists) { filter.init(this); this.filters.add(filter); }
}
复制代码

5、如果设置 testOnBorrow、testOnReturn、testWhileIdle 三个参数中的其中一个则必须配置 validationQuery 属性

private void validationQueryCheck() {  if (!(testOnBorrow || testOnReturn || testWhileIdle)) {    return;  }
if (this.validConnectionChecker != null) { return; }
if (this.validationQuery != null && this.validationQuery.length() > 0) { return; }
String errorMessage = "";
if (testOnBorrow) { errorMessage += "testOnBorrow is true, "; }
if (testOnReturn) { errorMessage += "testOnReturn is true, "; }
if (testWhileIdle) { errorMessage += "testWhileIdle is true, "; }
LOG.error(errorMessage + "validationQuery not set");}
复制代码


用户头像

wjchenge

关注

还未添加个人签名 2018.07.27 加入

还未添加个人简介

评论

发布
暂无评论
数据库连接池 -Druid 源码学习(二)_源码_wjchenge_InfoQ写作社区