Druid源码分析系列1:dataSource.init()的准备工作

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

本节,讲解

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290822.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件测试推荐专业,软件测试专业老师推荐信

尊敬的领导&#xff1a;您好&#xff01;首先感谢您在百忙之中抽出时间来阅读我学生XX的推荐信&#xff01;该生是XX大学软件测试专业应届毕业生&#xff0c;自进入XX大学以来&#xff0c;凭借自身扎实的基础和顽强拼搏的奋斗精神&#xff0c;经过几年不断的学习&#xff0c;在…

Android之用Handler实现主线程和子线程互相通信以及子线程和子线程之间的通信

1、上代码 activity_main.xml文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_p…

poj 2398 Toy Storage (计算几何,判断点和线段关系)

http://poj.org/problem?id2398 题意大概是说将一个盒子用n个board分成n1 部分 然后往里面放toy,给定盒子,board,和toy的坐标 问所有的toy放完后,有多少部分中有t个toy; 简单计算几何 需要判断的是点和直线的关系. 判断 某一点在直线左右侧 左右方向是相对前进方向的,只要指定…

[转]Android中pendingIntent的深入理解

转自;here pendingIntent字面意义&#xff1a;等待的&#xff0c;未决定的Intent。要得到一个pendingIntent对象&#xff0c;使用方法类的静态方法 getActivity(Context, int, Intent, int),getBroadcast(Context, int, Intent, int),getService(Context, int, Intent, int) 分…

叮,您有一份ML.NET 速查手册请查收!

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;7分钟&#xff09;本篇文章简要介绍 ML.NET 背景和面向 .NET 开发的特色功能&#xff0c;以及典型的机器学习编码示例&#xff0c;并分享自己整理的 ML.NET API 速查手册。微软MVP实验室研究员项斌微软全球最有价值专…

微信公众号开发之文本消息自动回复,以及系统关注自动回复,php代码

以tshop为例 直接上代码&#xff1a; 企业 cc_wx_sys表为自建&#xff0c;存储系统消息的配置的 字段: id type key status <?php /*** tpshop* * * 版权所有 2015-2027 深圳搜豹网络科技有限公司&#xff0c;并保留所有权利。* 网站地址: http://www.tp-shop.cn* -------…

java之ThreadLocal简单使用总结

1、介绍ThreadLocal 看安卓源码的时候&#xff0c;在这个类Looper.java &#xff0c;会有这个一句函数 static final ThreadLocal<Looper> sThreadLocal new ThreadLocal<Looper>(); 一开始我不是很懂ThreadLocal.java这个类&#xff0c;简单理解 ThreadLocal 就…

老师计算机传帮带工作总结,传帮带工作总结范文

传帮带工作总结范文一段时间的工作在不知不觉间已经告一段落了&#xff0c;回首这段不平凡的时间&#xff0c;有欢笑&#xff0c;有泪水&#xff0c;有成长&#xff0c;有不足&#xff0c;让我们好好总结下&#xff0c;并记录在工作总结里。那么如何把工作总结写出新花样呢&…

[Usaco2007 Demo][BZOJ1628] City skyline

1628: [Usaco2007 Demo]City skyline Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 320 Solved: 260[Submit][Status][Discuss]Description Input 第一行给出N&#xff0c;W第二行到第N1行:每行给出二个整数x,y&#xff0c;输入的x严格递增&#xff0c;并且第一个x总是1Out…

负载均衡(LB)集群 dr

LB、LVS介绍LB集群是load balance 集群的简写&#xff0c;翻译成中文就是负载均衡集群 LVS是一个实现负载均衡集群的开源软件项目 LVS架构从逻辑上可分为调度层(Director)、server集群层(Real server)和共享存储层LVS可分为三种工作模式: NAT(调度器将请求的目标ip即vip地址改为…

ASP.NET Core启动地址配置方法及优先级顺序 | .NET 6 版本

前言上次&#xff0c;我们讨论了如何通过配置或代码方式修改启动地址&#xff1a;《ASP.NET Core启动地址配置方法及优先级顺序》。不过是基于 .NET 5 版本的。由于 .NET 6 使用了最小 WEB API, 配置方式已经部分发生了变化。设置方法1. applicationUrl 属性launchSettings.jso…

php保存附件到指定服务器,如何在PHP中将电子邮件附件保存到服务器?

两天的大部分时间里,我一直在与PHP的电子邮件阅读功能作斗争.我正在编写一个脚本来读取邮箱中的电子邮件并将所有附件保存到服务器上.如果你曾经做过类似的事情,你可能会理解我的痛苦:PHP在电子邮件方面表现不佳!我已连接到POP3服务器,我可以迭代文件.这是代码的大致轮廓:if (!…

Java基础- super 和 this 解析

1. superkeyword表示超&#xff08;父&#xff09;类的意思。this变量代表对象本身。 2. super訪问父类被子类隐藏的变量或覆盖的方法。当前类假设是从超类继承而来的&#xff0c;当调用super.XX()就是调用基类版本号的XX&#xff08;&#xff09;方法。当中超类是近期的父类。…

Android之Handler和Loooper源码分析

1、handler在主线程和子线程互相通信&#xff08;子线程和子线程的通信&#xff09;简单使用 我们使用handler&#xff0c;可以实现主线程和子线程之间的相互通信&#xff0c;然后子线程和子线程之间的通信&#xff0c;如果不清楚&#xff0c;基本用法请先参考我的这篇博客 An…

VS2010 安装问题积累

vs2010 SP1安装不成功 日志文件里显示&#xff1a;error 1719 windows installer service could not be accessed 解决方法&#xff1a;Start, then Run, then type regedit Go to HKEY_LOCAL_MACHINE\SYSTEM\CURRENT CONTROL SET\SERVICES\MSIserver\WOW64 …

unix环境高级编程基础知识之第二篇(3)

看了unix环境高级编程第三章&#xff0c;把代码也都自己敲了一遍&#xff0c;另主要讲解了一些IO函数&#xff0c;read/write/fseek/fcntl&#xff1b;这里主要是c函数&#xff0c;比较容易&#xff0c;看多了就熟悉了。对fcntl函数讲解比较到位&#xff0c;它可以得到和改变打…

Avalonia跨平台入门第七篇之RadioButton的模板

前面其实已经玩耍过单选按钮,只不过一直好意思分享出来;今天终于可以正大光明的分享出来了,直接看效果吧:第一次使用然后的傻傻的版本(根据单选按钮的选中状态来切换二个图片);真的好Low:样式写法和WPF没太大区别:类似WPF中的触发器,使用了附加属性:前台具体使用方式:最终简单的…

svn之bash: syntax error near unexpected token `(‘ 解决办法

1、问题 svn update *****/网易(杭州)网络有限公司SSL-20170623001 出现这个错误 bash: syntax error near unexpected token ( 2、解决办法 改成下面的就行 把svn update *****/网易’(‘杭州’)‘网络有限公司SSL-20170623001

Angular 4.x 事件管理器及自定义EventManagerPlugin

在 Angular 中如何为同一个表达式绑定多个事件呢&#xff1f;如果我们这样做可能会是这样的&#xff1a; <div><button (click, mouseover)"onClick()">Click me</button> </div>复制代码在继续分析绑定多个事件之前&#xff0c;我们先来分析…

dell服务器报内存配置不正确,DELL 服务器系统提示错误解决的若干办法

《DELL 服务器系统提示错误解决的若干办法》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《DELL 服务器系统提示错误解决的若干办法(9页珍藏版)》请在人人文库网上搜索。1、DELL 服务器有时会若硬件的改动&#xff0c;在开机以后会提示错误信息。信息一般会提示在显示…