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");}
复制代码
评论