2019独角兽企业重金招聘Python工程师标准>>>
本节,讲解
dataSource.init();
打断点在
stop in com.alibaba.druid.pool.DruidDataSource.init
好,开始研究代码
public void init() throws SQLException {// 首先确定没有initedif (inited) {return;}//继续处理//获取lockfinal ReentrantLock lock = this.lock;try {//尝试获取locklock.lockInterruptibly();} catch (InterruptedException e) {throw new SQLException("interrupt", e);}//boolean init = false;try {//再次check没有初始化过,有点类似于double checkif (inited) {return;}//////// main[1] print initStackTrace// initStackTrace =// "java.lang.Thread.getStackTrace(Thread.java:1556)// com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:637)// com.alibaba.druid.pool.DruidDataSourceFactory.config(DruidDataSourceFactory.java:376)// com.alibaba.druid.pool.DruidDataSourceFactory.createDataSource(DruidDataSourceFactory.java:154)// com.alibaba.druid.pool.DruidDataSourceFactory.createDataSource(DruidDataSourceFactory.java:144)// user.defined.MyDataSourceFactory.getDataSource(MyDataSourceFactory.java:24)// org.apache.ibatis.builder.xml.XMLConfigBuilder.environmentsElement(XMLConfigBuilder.java:428)// org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:150)// org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:111)// org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:82)// org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:65)// test.Test.main(Test.java:23)// "initStackTrace = Utils.toString(Thread.currentThread().getStackTrace());
继续执行
//获取本数据源的ID标志this.id = DruidDriver.createDataSourceId();if (this.id > 1) {//同1个JVM里可能有多个数据源,就有多个IDlong delta = (this.id - 1) * 100000;this.connectionIdSeed.addAndGet(delta);this.statementIdSeed.addAndGet(delta);this.resultSetIdSeed.addAndGet(delta);this.transactionIdSeed.addAndGet(delta);}
然后处理JDBC
// 处理urlif (this.jdbcUrl != null) {this.jdbcUrl = this.jdbcUrl.trim();//进去没做什么事情initFromWrapDriverUrl();}
接下来是插件机制,就是初始化了插件
然后是确定dbType
if (this.dbType == null || this.dbType.length() == 0) {this.dbType = JdbcUtils.getDbType(jdbcUrl, null);}
这个是根据url的前缀来做的。
======================================================
//构建connectPropertiesif (JdbcConstants.MYSQL.equals(this.dbType) || //JdbcConstants.MARIADB.equals(this.dbType)) {//boolean cacheServerConfigurationSet = false;if (this.connectProperties.containsKey("cacheServerConfiguration")) {cacheServerConfigurationSet = true;} else if (this.jdbcUrl.indexOf("cacheServerConfiguration") != -1) {cacheServerConfigurationSet = true;}if (cacheServerConfigurationSet) {this.connectProperties.put("cacheServerConfiguration", "true");}}
//简单的参数checkif (maxActive <= 0) {throw new IllegalArgumentException("illegal maxActive " + maxActive);}if (maxActive < minIdle) {throw new IllegalArgumentException("illegal maxActive " + maxActive);}if (getInitialSize() > maxActive) {throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActive " + maxActive);}if (timeBetweenLogStatsMillis > 0 && useGlobalDataSourceStat) {throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGlobalDataSourceStat=true");}if (maxEvictableIdleTimeMillis < minEvictableIdleTimeMillis) {throw new SQLException("maxEvictableIdleTimeMillis must be grater than minEvictableIdleTimeMillis");}
// 处理driverClassif (this.driverClass != null) {this.driverClass = driverClass.trim();}////////什么都不做initFromSPIServiceLoader();
//确定driverClass创建实例if (this.driver == null) {if (this.driverClass == null || this.driverClass.isEmpty()) {this.driverClass = JdbcUtils.getDriverClassName(this.jdbcUrl);}if (MockDriver.class.getName().equals(driverClass)) {driver = MockDriver.instance;} else {driver = JdbcUtils.createDriver(driverClassLoader, driverClass);}} else {if (this.driverClass == null) {this.driverClass = driver.getClass().getName();}}
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.init(), line=718 bci=649
718 initCheck();main[1] step
>
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.initCheck(), line=942 bci=0
942 if (JdbcUtils.ORACLE.equals(this.dbType)) {main[1] next
>
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.initCheck(), line=955 bci=125
955 } else if (JdbcUtils.DB2.equals(dbType)) {main[1] next
>
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.initCheck(), line=958 bci=142
958 }
===========接下来,就是initExceptionSorter(); 看看,怎么执行的。
private void initExceptionSorter() {//从这里开始if (exceptionSorter instanceof NullExceptionSorter) {if (driver instanceof MockDriver) {return;}} else if (this.exceptionSorter != null) {return;}String realDriverClassName = driver.getClass().getName();if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //|| realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {//处理这个this.exceptionSorter = new MySqlExceptionSorter();
---创建ConnectionChecker
private void initValidConnectionChecker() {//here//String realDriverClassName = driver.getClass().getName();if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //|| realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {//针对mysql创建this.validConnectionChecker = new MySqlValidConnectionChecker();} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)|| realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {this.validConnectionChecker = new OracleValidConnectionChecker();} else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_JTDS)) {this.validConnectionChecker = new MSSQLValidConnectionChecker();} else if (realDriverClassName.equals(JdbcConstants.POSTGRESQL_DRIVER)) {this.validConnectionChecker = new PGValidConnectionChecker();}}
public MySqlValidConnectionChecker(){try {clazz = Utils.loadClass("com.mysql.jdbc.MySQLConnection");if (clazz == null) {clazz = Utils.loadClass("com.mysql.cj.jdbc.ConnectionImpl");}if (clazz != null) {ping = clazz.getMethod("pingInternal", boolean.class, int.class);}if (ping != null) {usePingMethod = true;}} catch (Exception e) {LOG.warn("Cannot resolve com.mysql.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);}configFromProperties(System.getProperties());}
接着初始化QueryChecker
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.validationQueryCheck(), line=912 bci=4
912 if (!(isTestOnBorrow() || isTestOnReturn() || isTestWhileIdle())) {main[1] step
>
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.validationQueryCheck(), line=916 bci=22
916 if (this.validConnectionChecker != null) {main[1] print validConnectionCheckervalidConnectionChecker = "com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker@2d1ef81a"
main[1] step
>
Step completed: "thread=main", com.alibaba.druid.pool.DruidDataSource.validationQueryCheck(), line=917 bci=29
917 return;main[1] step
看来不需要创建了。