Hikari目前已经是springboot的默认数据库连接池,并且以高效和轻量著称,因为代码量比较少,所以可以阅读一下,学习一下,github地址:HikariCP

HikariDataSource

成员变量

  • private final AtomicBoolean isShutdown = new AtomicBoolean();

线程安全的连接池是否关闭的标识符

  • private final HikariPool fastPathPool;

通过传入的配置创建的实际连接池的对象引用

  • private volatile HikariPool pool;

通过自身的配置创建的实际连接池的对象引用,注意这里的volatile,这个是为双重检查锁定模式使用的

构造器

  • 默认构造器
public HikariDataSource()
{super();fastPathPool = null;
}

默认构造器可以看到是将配置设置一下默认值,然后初始化一下HikariPool为null

  • 带参构造器
public HikariDataSource(HikariConfig configuration)
{configuration.validate();configuration.copyStateTo(this);LOGGER.info("{} - Starting...", configuration.getPoolName());pool = fastPathPool = new HikariPool(this);LOGGER.info("{} - Start completed.", configuration.getPoolName());this.seal();
}

首先是对传入的配置参数进行检查是否符合要求,如果符合要求将参数复制到本对象中,然后开始创建线程池,将创建的线程池的引用赋给fastPathPool,然后将是否封闭的值改成true防止被恶意修改

数据库连接池实现方法

  • public Connection getConnection() throws SQLException
@Override
public Connection getConnection() throws SQLException
{if (isClosed()) {throw new SQLException("HikariDataSource " + this + " has been closed.");}if (fastPathPool != null) {return fastPathPool.getConnection();}// See http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_JavaHikariPool result = pool;if (result == null) {synchronized (this) {result = pool;if (result == null) {validate();LOGGER.info("{} - Starting...", getPoolName());try {pool = result = new HikariPool(this);this.seal();}catch (PoolInitializationException pie) {if (pie.getCause() instanceof SQLException) {throw (SQLException) pie.getCause();}else {throw pie;}}LOGGER.info("{} - Start completed.", getPoolName());}}}return result.getConnection();
}

首先检查该连接池是否已经关闭,就是成员变量的isShutdown的值。如果已经关闭,抛出已经关闭的异常。如果连接池初始化成功的话,直接调用连接池的getConnection()方法返回。如果没有初始化,那么通过自身的配置信息初始化一个数据库连接池赋给pool字段。然后用这个新创建的连接池返回连接。
这里代码那么长主要是因为用了双重检查锁定模式,防止在多线程的情况中初始化一个不完整的数据库连接池。具体双重检查锁定模式的意义和实现,作者在代码中加了它的维基百科地址:双重检查锁定模式

  • public T unwrap(Class iface) throws SQLException
@Override
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> iface) throws SQLException
{if (iface.isInstance(this)) {return (T) this;}HikariPool p = pool;if (p != null) {final DataSource unwrappedDataSource = p.getUnwrappedDataSource();if (iface.isInstance(unwrappedDataSource)) {return (T) unwrappedDataSource;}if (unwrappedDataSource != null) {return unwrappedDataSource.unwrap(iface);}}throw new SQLException("Wrapped DataSource is not an instance of " + iface);
}

这个方法是为了将连接池转换成指定的数据库连接池类型,如果是的,进行强制转换后返回

  • public boolean isWrapperFor(Class<?> iface) throws SQLException
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException
{if (iface.isInstance(this)) {return true;}HikariPool p = pool;if (p != null) {final DataSource unwrappedDataSource = p.getUnwrappedDataSource();if (iface.isInstance(unwrappedDataSource)) {return true;}if (unwrappedDataSource != null) {return unwrappedDataSource.isWrapperFor(iface);}}return false;
}

这个方法是来判断当前的对象是不是指定类的实例

HikariConfigMXBean接口方法

  • public void setMetricRegistry(Object metricRegistry)
@Override
public void setMetricRegistry(Object metricRegistry)
{boolean isAlreadySet = getMetricRegistry() != null;super.setMetricRegistry(metricRegistry);HikariPool p = pool;if (p != null) {if (isAlreadySet) {throw new IllegalStateException("MetricRegistry can only be set one time");}else {p.setMetricRegistry(super.getMetricRegistry());}}
}

设置度量标准注册表,先调用父类HikariConfig的set方法来检查和设置,如果没有问题、连接池也初始化完成并且没有设置过,就可以进行参数的设置

  • public void setMetricsTrackerFactory(MetricsTrackerFactory metricsTrackerFactory)

同上

  • public void setHealthCheckRegistry(Object healthCheckRegistry)

同上

连接池特殊方法

  • public boolean isRunning()
public boolean isRunning()
{return pool != null && pool.poolState == POOL_NORMAL;
}

检查连接池是否正在运行,判断条件是连接池存在并且状态是正常状态

  • public void evictConnection(Connection connection)
public void evictConnection(Connection connection)
{HikariPool p;if (!isClosed() && (p = pool) != null && connection.getClass().getName().startsWith("com.zaxxer.hikari")) {p.evictConnection(connection);}
}

将指定的连接从连接池中去除。判断条件是连接池没有关闭并且连接池存在并且这个连接是hikari数据库连接池的连接,以上为真的情况下,调用HikariPool的方法去除该连接

  • public void close()
@Override
public void close()
{if (isShutdown.getAndSet(true)) {return;}HikariPool p = pool;if (p != null) {try {LOGGER.info("{} - Shutdown initiated...", getPoolName());p.shutdown();LOGGER.info("{} - Shutdown completed.", getPoolName());}catch (InterruptedException e) {LOGGER.warn("{} - Interrupted during closing", getPoolName(), e);Thread.currentThread().interrupt();}}
}

关闭连接池,先判断是否已经关闭,如果是的就结束,如果不是,调用HikariPool的shutdown()方法进行关闭。这里比较特殊的是getAndSet()这个方法,因为涉及到原子类的赋值和取值,所以稍微有一点复杂

【HikariCP】【HikariDataSource】源码学习相关推荐

  1. Shiro源码学习之二

    接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws Authent ...

  2. Shiro源码学习之一

    一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId&g ...

  3. mutations vuex 调用_Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)...

    前言 Vuex源码系列不知不觉已经到了第六篇.前置的五篇分别如下: 长篇连载:Vuex源码学习(一)功能梳理 长篇连载:Vuex源码学习(二)脉络梳理 作为一个Web前端,你知道Vuex的instal ...

  4. vue实例没有挂载到html上,vue 源码学习 - 实例挂载

    前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...

  5. 2021-03-19Tomcat源码学习--WebAppClassLoader类加载机制

    Tomcat源码学习--WebAppClassLoader类加载机制 在WebappClassLoaderBase中重写了ClassLoader的loadClass方法,在这个实现方法中我们可以一窥t ...

  6. jQuery源码学习之Callbacks

    jQuery源码学习之Callbacks jQuery的ajax.deferred通过回调实现异步,其实现核心是Callbacks. 使用方法 使用首先要先新建一个实例对象.创建时可以传入参数flag ...

  7. JDK源码学习笔记——Integer

    一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...

  8. DotText源码学习——ASP.NET的工作机制

    --本文是<项目驱动学习--DotText源码学习>系列的第一篇文章,在这之后会持续发表相关的文章. 概论 在阅读DotText源码之前,让我们首先了解一下ASP.NET的工作机制,可以使 ...

  9. Vuex源码学习(五)加工后的module

    没有看过moduleCollection那可不行!Vuex源码学习(四)module与moduleCollection 感谢提出代码块和截图建议的小伙伴 代码块和截图的区别: 代码块部分希望大家按照我 ...

  10. 我的angularjs源码学习之旅2——依赖注入

    依赖注入起源于实现控制反转的典型框架Spring框架,用来削减计算机程序的耦合问题.简单来说,在定义方法的时候,方法所依赖的对象就被隐性的注入到该方法中,在方法中可以直接使用,而不需要在执行该函数的时 ...

最新文章

  1. 分享个网盘,个人觉得很不错!
  2. CentOS查看CPU信息、位数、多核信息
  3. ios 使用gcd 显示倒计时
  4. 《分布式操作系统》知识点(29~34)五
  5. xxx is already defined as object xxx+intellij新建一个scala的maven项目+找不到或无法载入主要类别hello问题解决
  6. 前端学习(2371):组件之间的通讯方式
  7. 信息学奥赛C++语言:删除试题
  8. Kubernetes 上对应用程序进行故障排除的 6 个技巧
  9. svn怎么检出两个地址项目_svn 检出项目报错
  10. 转 java synchronized详解
  11. 0 基础转行 Android 工程师是种怎样的体验?
  12. Centos下 为Firefox安装Flash插件
  13. iphone 开发第四天 - 字符串
  14. svn中文扩展包安装
  15. 互动快报读报软件绿色版 v5.061
  16. 百度“有啊”困局之源:流量到交易的转化
  17. HTML动画能在手机播放吗,如何使动画在手机中屏幕适配
  18. OpenGL ES 之uniform和varying
  19. xp 架设网站服务器,WinXP如何设置iis服务器?WinXP iis服务器设置教程
  20. 劝说语合理使用计算机,用一句名言来劝说家长让孩子接触计算机

热门文章

  1. HIT oj题解1002 - A+B+C
  2. Lake Shore低温温度传感器综合介绍
  3. MyBatis3 映射boolean 类型注意事项
  4. 合适的工作就是好工作
  5. 创新案例分享 | 构建高效、智能人力管理系统,助力公司战略转型
  6. silabs ZLL
  7. linux 自启动iptable_保存iptable规则并开机自动加载
  8. DotNet C#开源资源汇总
  9. 晓晨高效IP提取工具 附源码
  10. Unity 之 ToLua框架中UI.Dropdown组件动态添加Options