继续探究 DruidDataSource 核心类 init 初始化方法
类 DruidDataSource 第 810 行
lock.lockInterruptibly();
复制代码
ReentrantLock 锁有几种:lock、tryLock、tryLock(long timeout, TimeUnit unit)、lockInterruptibly。
这里简单说下 lock 和 lockInterruptibly 的区别
lock 阻塞等待获取锁,优先考虑获取锁,待获取锁成功后,才响应中断。
lockInterruptibly 优先考虑响应中断,而不是响应锁的普通获取或重入获取。
ReentrantLock.lockInterruptibly 允许在等待时由其它线程调用等待线程的 Thread.interrupt 方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个 InterruptedException。 ReentrantLock.lock 方法不允许 Thread.interrupt 中断,即使检测到 Thread.isInterrupted,一样会继续尝试获取锁,失败则继续休眠。只是在最后获取锁成功后再把当前线程置为 interrupted 状态,然后再中断线程。
接下来
initStackTrace = Utils.toString(Thread.currentThread().getStackTrace());//获取当前线程堆栈跟踪元素数组再转换为String
复制代码
线程类的 getStackTrace() 方法返回一个堆栈跟踪元素数组,表示线程的堆栈转储。数组的第一个元素表示堆栈的顶部,它是序列中的最后一个方法调用。数组的最后一个元素表示堆栈的底部,这是序列中的第一个方法调用。
Utils 是 druid 工具类这里定义另一个 toString 方法将 StackTraceElement[]数组转成字符串,如下:
public static String toString(StackTraceElement[] stackTrace) { StringBuilder buf = new StringBuilder(); for (StackTraceElement item : stackTrace) { buf.append(item.toString()); buf.append("\n"); } return buf.toString(); }
复制代码
this.id = DruidDriver.createDataSourceId(); if (this.id > 1) { long delta = (this.id - 1) * 100000; this.connectionIdSeedUpdater.addAndGet(this, delta); this.statementIdSeedUpdater.addAndGet(this, delta); this.resultSetIdSeedUpdater.addAndGet(this, delta); this.transactionIdSeedUpdater.addAndGet(this, delta); }
复制代码
connectionIdSeedUpdater、statementIdSeedUpdater、resultSetIdSeedUpdater、transactionIdSeedUpdater
这几个都是在抽象类 DruidAbstractDataSource 定义的 AtomicLongFieldUpdater<DruidAbstractDataSource>AtomicLongFieldUpdater 可以对指定"类的 'volatile long'类型的成员"进行原子更新。它是基于反射原理实现的
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) { Class<?> caller = Reflection.getCallerClass(); if (AtomicLong.VM_SUPPORTS_LONG_CAS) return new CASUpdater<U>(tclass, fieldName, caller); else return new LockedUpdater<U>(tclass, fieldName, caller); }
复制代码
说明:newUpdater()的作用是获取一个 AtomicIntegerFieldUpdater 类型的对象。它实际上返回的是 CASUpdater 对象,或者 LockedUpdater 对象;具体返回哪一个类取决于 JVM 是否支持 long 类型的 CAS 函数。这里是获取数据库操作相关(connection、statement、resultSet、transction)的种子 ID,并追加了 delta.
if (this.jdbcUrl != null) { this.jdbcUrl = this.jdbcUrl.trim(); initFromWrapDriverUrl(); }
for (Filter filter : filters) { filter.init(this); }
if (this.dbTypeName == null || this.dbTypeName.length() == 0) { this.dbTypeName = JdbcUtils.getDbType(jdbcUrl, null); }
DbType dbType = DbType.of(this.dbTypeName); if (JdbcUtils.isMysqlDbType(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"); } }
复制代码
这段初始化了 jdbcUrl 并且获取数据库类型名称 DbType 是个枚举类,定义了市场上几乎所有的数据库名其中 JdbcUtils 类会发现这段代码
static { try { ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader(); if (ctxClassLoader != null) { for (Enumeration<URL> e = ctxClassLoader.getResources("META-INF/druid-driver.properties"); e.hasMoreElements();) { URL url = e.nextElement();
Properties property = new Properties();
InputStream is = null; try { is = url.openStream(); property.load(is); } finally { JdbcUtils.close(is); }
DRIVER_URL_MAPPING.putAll(property); } } } catch (Exception e) { LOG.error("load druid-driver.properties error", e); } }
复制代码
可见驱动都在该属性文件中 druid-driver.properties 打开看果然
jdbc:derby:=org.apache.derby.jdbc.EmbeddedDriver jdbc:mysql:=com.mysql.jdbc.Driverjdbc:log4jdbc:=net.sf.log4jdbc.DriverSpyjdbc:oracle:=oracle.jdbc.driver.OracleDriverjdbc:microsoft:=com.microsoft.jdbc.sqlserver.SQLServerDriver jdbc:jtds:=net.sourceforge.jtds.jdbc.Driver jdbc:postgresql:=org.postgresql.Driver jdbc:fake:=com.alibaba.druid.mock.MockDriver jdbc:hsqldb:=org.hsqldb.jdbcDriver jdbc:db2:=COM.ibm.db2.jdbc.app.DB2Driverjdbc:sqlite:=org.sqlite.JDBC jdbc:ingres:=com.ingres.jdbc.IngresDriver jdbc:h2:=org.h2.Driver jdbc:mckoi:=com.mckoi.JDBCDriverjdbc:clickhouse:=ru.yandex.clickhouse.ClickHouseDriverjdbc:highgo:=com.highgo.jdbc.Driver
复制代码
参考:
https://blog.csdn.net/u013308490/article/details/83062433
https://blog.csdn.net/Shujie_L/article/details/123777561
https://blog.csdn.net/wangxiaotongfan/article/details/51798969
评论