IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Druid源码分析(三)-- 初始化DataSource2 -> 正文阅读

[大数据]Druid源码分析(三)-- 初始化DataSource2

Druid源码分析(三)-- 初始化DataSource2

Druid源码分析(三)-- 初始化DataSource2

init

昨天分析了init 函数的双重校验+锁,今天接着往下看源码

// DruidDataSource.java#init()
// 获取堆栈信息
initStackTrace = Utils.toString(Thread.currentThread().getStackTrace());
// 创建数据源id 
this.id = DruidDriver.createDataSourceId();

这里用的是原子类Integer,来保证自增是线程安全的

// DruidDriver.java
private final static AtomicInteger dataSourceIdSeed = new AtomicInteger(0);
public static int createDataSourceId() {
	return dataSourceIdSeed.incrementAndGet();
}

多数据源处理

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);
}

接下来是加载filters,自带的监控filter等在这里加载

for (Filter filter : filters) {
	// filter初始化
	filter.init(this);
}

// StatFilter.java
// 以监控filter为例,查看下init的实现,其他filter类似
public void init(DataSourceProxy dataSource) {
	// 加锁,避免重复初始化
    lock.lock();
    try {
    	// 如果filter的 dbType 为空,用数据源的dbType 
        if (this.dbType == null) {
            this.dbType = DbType.of(dataSource.getDbType());
        }
		// 从配置文件加载配置
        configFromProperties(dataSource.getConnectProperties());
        configFromProperties(System.getProperties());
    } finally {
    	// 解锁
        lock.unlock();
    }
}

接着往下看,是校验dbTypeName ,没配置的话会调用JdbcUtils 的函数通过jdbcUrl来获取

// 如果没有设置数据源TypeName,或通过jdbcUrl来获取
if (this.dbTypeName == null || this.dbTypeName.length() == 0) {
    this.dbTypeName = JdbcUtils.getDbType(jdbcUrl, null);
}

// JdbcUtils.java
// 从这个函数可以看出druid连接池支持的数据库类型是非常多的
public static DbType getDbTypeRaw(String rawUrl, String driverClassName) {
   	...
    if (rawUrl.startsWith("jdbc:mysql:") || rawUrl.startsWith("jdbc:cobar:")
            || rawUrl.startsWith("jdbc:log4jdbc:mysql:")) {
        return DbType.mysql;
    } else if (rawUrl.startsWith("jdbc:mariadb:")) {
        return DbType.mariadb;
    } else if (rawUrl.startsWith("jdbc:oracle:") || rawUrl.startsWith("jdbc:log4jdbc:oracle:")) {
        return DbType.oracle;
    ...
 }

下面就是校验一些参数的合法性

// 校验最大连接池数量
if (maxActive <= 0) {
    throw new IllegalArgumentException("illegal maxActive " + maxActive);
}

if (maxActive < minIdle) {
    throw new IllegalArgumentException("illegal maxActive " + maxActive);
}

// 这里默认连接池数量 DEFAULT_INITIAL_SIZE = 0;
if (getInitialSize() > maxActive) {
    throw new IllegalArgumentException("illegal initialSize " + this.initialSize + ", maxActive " + maxActive);
}

SPI机制

自定义的filter在这里加载

private void initFromSPIServiceLoader() {
	// 默认值是false,可以在配置文件通过druid.load.spifilter.skip 设置值为true,即可跳过这个加载
    if (loadSpifilterSkip) {
        return;
    }

    if (autoFilters == null) {
        List<Filter> filters = new ArrayList<Filter>();
        // 通过SPI机制去加载Filter
        ServiceLoader<Filter> autoFilterLoader = ServiceLoader.load(Filter.class);
		// 开启了自动加载 AutoLoad 注解的filter 才会被加载
        for (Filter filter : autoFilterLoader) {
            AutoLoad autoLoad = filter.getClass().getAnnotation(AutoLoad.class);
            if (autoLoad != null && autoLoad.value()) {
                filters.add(filter);
            }
        }
        autoFilters = filters;
    }

    for (Filter filter : autoFilters) {
        ...
        // 把通过SPI加载的filter 加到filter 列表里
        addFilter(filter);
    }
}

总结

我发现开源项目大多都有SPI机制来支持用户自定义filter ,平常工作中项目的扩展性也可以考虑使用这个机制

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-16 11:21:36  更:2022-05-16 11:22:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 10:39:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码