Druid源码分析系列1:dataSource.init()的准备工作
生活随笔
收集整理的這篇文章主要介紹了
Druid源码分析系列1:dataSource.init()的准备工作
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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看來不需要創建了。
轉載于:https://my.oschina.net/qiangzigege/blog/884024
總結
以上是生活随笔為你收集整理的Druid源码分析系列1:dataSource.init()的准备工作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用ABBYY FineReader进行
- 下一篇: 微信公众号开发之文本消息自动回复,以及系