Createsequence's Blog

一个努力前进的程序猿


  • 首页

  • 标签

  • 分类

  • 归档

  • 搜索

发布自己的jar包到Maven官方仓库

发表于 2022-02-18 | 分类于 杂七乱八
字数统计: 2.3k

一、申请GroupId

我们知道,一个maven坐标由groupId,artifactId和version组成,后两者可以在pom中调整,而可以用在中央仓库的 groupId需要申请。由于 Maven 中央仓库由 sonatype 公司进行运营,所以我们首先需要注册一个sonatype账号,通过该账号去申请一个 groupId。

1、注册

注册没什么好说的,按顺序填就行,需要注意用户名最好不要用中文。

image-20220215144939190

2、申请

这里的操作跟GitHub很像,新增相当于提出一个issues:

image-20220215150018531
image-20220215150018531

然后填写信息:

image-20220215150401093

阅读全文 »

Mybatis源码学习(三):映射文件中sql的解析

发表于 2021-07-11 | 分类于 Mybatis
字数统计: 4.2k

概述

根据上一篇文章,我们了解了 Mybatis 如何在加载配置文件后,根据指定配置方式寻找接口并且完成映射文件信息与接口的绑定的。在本篇文章,我们将延续上文,结合源码阐述映射文件中方法声明里的 sql 被解析为 java 对象的过程。

这是关于 Mybatis 的第三篇文章,前文:

Mybatis源码学习(一):配置文件的加载

Mybatis源码学习(二):Mapper接口的绑定

一、sql解析

image-20210711012449848

1.XMLMapperBuilder

Sql 解析与 MappedStatement的生成都在 XMLMapperBuilder 进行。根据上文可知,在 XMLMapperBuilder 的 parsePendingStatements()方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void parsePendingStatements() {
// 获取所有映射文件中的方法声明
Collection<XMLStatementBuilder> incompleteStatements = configuration.getIncompleteStatements();
synchronized (incompleteStatements) {
Iterator<XMLStatementBuilder> iter = incompleteStatements.iterator();
while (iter.hasNext()) {
try {
// 遍历并转换为Statement对象
iter.next().parseStatementNode();
iter.remove();
} catch (IncompleteElementException e) {
// Statement is still missing a resource...
}
}
}
}

其中,Configuration类中的IncompleteStatements是在XMLMapperBuilder.parse()时添加进去的,我们可以理解他是一个刚从配置文件中根据<select><delete><update><insert>标签名拿到的 XML 节点,还没有做任何解析。

阅读全文 »

Mybatis源码学习(二):Mapper接口的绑定

发表于 2021-06-14 | 分类于 Mybatis
字数统计: 4.6k

概述

根据上一篇文章,我们了解了 Mybatis 的配置文件是如何被加载的。在完成这一步之后,Mybatis 还需要根据配置文件中指定的路径去加载 Mapper 接口与写有 sql 的相应映射文件,最终完成两者的绑定。

在本篇文章,我们将结合源码阐述这个过程。

这是关于 Mybatis 的第二篇文章,前文:

Mybatis源码学习(一):配置文件的加载

一、加载接口

image-20210609000011106

1.XMLConfigBuilder

见名知意,这个类的作用在于解析映射文件,根据上文,我们会了解到他里面有各种 标签名+Element为名的解析方法,其中,针对 Mapper 映射文件解析方法就是mapperElement()。

在开始之前,我们需要知道,在映射文件中有四种指定 Mybatis 接口的方式:

阅读全文 »

Mybatis源码学习(一):配置文件的加载

发表于 2021-06-05 | 分类于 Mybatis
字数统计: 2.5k

概述

我们知道,一个框架的运行,往往都从配置文件的加载开始,本篇文章作为 Mybatis 源码学习的第一篇文章,将结合源码,阐述 Mybatis 是如何加载 mybatis-config.xml 配置文件的。

Mybatis 版本:3.5.8

JDK 版本:1.8

Mysql 版本:5.6.51

一、输入流的读取

我们根据源码给的测试用例,可以知道 Mybatis 可以通过以下代码获取 Xml 配置文件并转为配置类:

1
2
3
4
5
String resource = "org/apache/ibatis/builder/MinimalMapperConfig.xml";
try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
XMLConfigBuilder builder = new XMLConfigBuilder(inputStream);
Configuration config = builder.parse();
}

拿到全局配置类 Configuration 以后就可以通过SqlSessionFactoryBuilder().build()方法去创建SqlSessionFactory了。当然,SqlSessionFactoryBuilder().build()有多个重载方法,但是无外乎都要经过转换为 Configuration 这一步。

整个过程就分为三步:

阅读全文 »

AQS源码分析

发表于 2021-02-11 | 分类于 多线程
字数统计: 4.3k

概述

当我们提到 juc 包下的锁,就不得不联系到 AbstractQueuedSynchronizer 这个类,这个类就是大名鼎鼎的 AQS,AQS 按字面意思翻译为抽象队列同步器,调用者可以通过继承该类快速的实现同步多线程下的同步容器。不管是我们熟悉的 ReadWriteLock 亦或是 ReentrantLock,或者 CountDownLatch 与 Semaphore,甚至是线程池类 ThreadPoolExecutor 都继承了 AQS。

在本文,将深入源码,了解 AQS 的运行机制,了解通过 AQS 实现非公平锁,公平锁,可重入锁等的原理。

一、AQS 中的数据结构

AQS 的底层数据结构其实是一条双向链表以及一个代表锁状态的变量 state。当加锁后,state会改变,而竞争锁的线程会被封装到节点中形成链表,并且尝试改变 state以获取锁。

1.等待队列

在 AQS 中有一个 Node 内部类,该类即为链表的节点类。当通过 AQS 竞争锁的时候,线程会被封装到一个对应的节点中,多个竞争不到锁的线程最终会连成一条链表,这条链表上节点代表的线程处于等待状态,因此我们称之为等待队列,也就是 CLH。

节点类中封装了竞争锁的线程的等待状态:

  • CANCELLED:1,表示当前结点已取消等待。当timeout或被中断(响应中断的情况下),会触发变更为此状态,进入该状态后的结点将不会再变化。
  • SIGNAL:-1,表示后继结点在等待当前结点唤醒。后继结点入队时,会将前继结点的状态更新为SIGNAL。
  • CONDITION:-2,表示结点等待在Condition上,当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中,等待获取同步锁。
  • PROPAGATE:-3,共享模式下,前继结点不仅会唤醒其后继结点,同时也可能会唤醒后继的后继结点。
  • 0:新节点入队时的默认状态。

和线程池中的状态一样,Node 只有小于 0 的时候才处于正常的等待状态中,因此很多地方通过判断是否小于 0 来确定节点是否处于等待状态。

阅读全文 »

线程池源码分析

发表于 2021-02-09 | 分类于 多线程
字数统计: 5.1k

概述

在 java 中,线程池 ThreadPoolExecutor 是一个绕不过去的类,它是享元模式思想的体现,通过在容器中创建一定数量的线程加以重复利用,从而避免频繁创建线程带来的额外开销。一个设置合理的线程池可以提高任务响应的速度,并且避免线程数超过硬件能力带来的意外情况。

在本文,将深入线程池源码,了解线程池的底层实现与运行机制。

一、构造方法

ThreadPoolExecutor 类一共提供了四个构造方法,我们基于参数最完整构造方法了解一下线程池创建所需要的变量:

1
2
3
4
5
6
7
8
public ThreadPoolExecutor(int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 非核心线程闲置存活时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 工作队列
ThreadFactory threadFactory, // 创建线程使用的线程工厂
RejectedExecutionHandler handler // 拒绝策略) {
}
  • 核心线程数:即长期存在的线程数,当线程池中运行线程未达到核心线程数时会优先创建新线程;
  • 最大线程数:当核心线程已满,工作队列已满,同时线程池中线程总数未超过最大线程数,会创建非核心线程;
  • 非核心线程闲置存活时间:当非核心线程闲置的时的最大存活时间;
  • 时间单位:非核心线程闲置存活时间的时间单位;
  • 任务队列:当核心线程满后,任务会优先加入工作队列,等等待核心线程消费;
  • 线程工厂:线程池创建新线程时使用的线程工厂;
  • 拒绝策略:当工作队列与线程池都满时,用于执行的策略;

二、线程池状态

1.线程池状态

线程池拥有一个 AtomicInteger 类型的成员变量 ctl ,通过位运算分别使用 ctl 的高位低位以便在一个值中存储线程数量以及线程池状态。

阅读全文 »

synchronized底层原理探究

发表于 2021-02-06 | 分类于 多线程
字数统计: 4.1k

概述

说起多线程同步,一般的方案就是加锁,而在 java 中,提到加锁就想起 juc 包提供的 Lock 接口实现类与默认的关键字 synchronized 。我们常听到,juc 下的锁大多基于 AQS,而 AQS 的锁机制基于 CAS,相比起 CAS 使用的自旋锁,Synchronized 是一种重量级的锁实现。

实际上,在 JDK6 之后,synchronized 逐渐引入了锁升级机制,它将会有一个从轻量级到重量级的逐步升级的过程。本文将简单的介绍 synchronized 的底层实现原理,并且介绍 synchronized 的锁升级机制。

一、synchronized 的底层实现

synchronized 意为同步,它可以用于修饰静态方法,实例方法,或者一段代码块。

它是一种可重入的对象锁。当修饰静态方法时,锁对象为类;当修饰实例方法时,锁对象为实例;当修饰代码块时,锁可以是任何非 null 的对象。

由于其底层的实现机制,synchronized 的锁又称为监视器锁。

1.同步代码块

当我们反编译一个含有被 synchronized 修饰的代码块的文件时,我们可以看到类似如下指令:

image-20210210174821495
image-20210210174821495
阅读全文 »

《趣谈网络协议》读书笔记(五):TCP与UDP

发表于 2021-01-14 | 分类于 计算机网络
字数统计: 6.1k

概述

此文为极客时间趣谈网络协议第二模块第10讲至第12讲的的学习笔记。

主要内容包括传输层的两个重要协议 TCP 与 UDP 协议,以及 TCP 是如何建立稳定连接。

一、TCP与UDP的区别

1.定义

传输控制协议:(TCP,Transmission Control Protocol)是为了在不可靠的互联网络上提供可靠的端到端字节流而专门设计的一个传输协议

用户数据报协议:(UDP,User Datagram Protocol)是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

2.区别

就其特性而言,TCP 是面向连接的,UDP 是面向无连接的,更直白的说,TCP 是有状态的,UDP 是无状态的。

TCP 在连接之前,会进行三次握手以建立连接,这里的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性。

阅读全文 »

《趣谈网络协议》读书笔记(四):网关与路由协议

发表于 2020-12-25 | 分类于 计算机网络
字数统计: 3.8k

概述

此文为极客时间趣谈网络协议第二模块“从第二层到第三层”中,第四节和第五节的学习笔记。

主要内容包括网关,路由等,介绍了设备是如何在多个局域网间通过网关进行通信的。

一、网关

在前文,我们了解到,局域网中的机器可以向另一局域网发出请求,在同一个局域网中的请求最后会抵达路由器或者交换机,最后再转发出去,而之所以请求都能到达一处,就在于他们所在的局域网中有一个统一的网关(Gateway)。

1.数据是如何到网关的

首先我们需要了解数据包中 MAC 头与 IP 头的结构:

我们知道,网络层总是一层套一层的,因此 MAC 包里包含 IP 包,MAC 头下会有 IP 头。

MAC 头的结构

image-20201225140407048
image-20201225140407048
阅读全文 »

《趣谈网络协议》读书笔记(三):ICMP协议与ping命令

发表于 2020-12-24 | 分类于 计算机网络
字数统计: 1.7k

概述

此文为极客时间趣谈网络协议第二模块“从第二层到第三层”中,第三节的学习笔记。

主要内容包括 ICMP 协议中的查询报文与差错报文,ping 命令的整个执行过程,Linux 的Traceroute命令是如何通过差错报文获取网络状态的。

一、ICMP协议

一般情况下,我们想要知道网络是否畅通,或者服务器是否正常运行,会使用 ping 命令,而 ping 命令依赖的协议就是 ICMP 协议。

ICMP 协议全程为 Internet Control Message Protocol,即互联网控制报文协议。它是介于 IP 层与 TCP 层之间的协议,一般认为属于 IP 层协议,也就是网络层协议。它被封装在 IP 包中,IP 协议用它来与其他主机交换错误报文或者一些其他的网络情况。

img

ICMP 报文有两种类型,一种是查询报文,比如 ping 命令;另一种是差错报文。

1.查询报文

ping 命令是查询报文一种,是一种主动请求,并且获得主动应答的 ICMP 协议,它在后面加了自己的格式。

阅读全文 »
123…10

99 日志
15 分类
22 标签
RSS
© 2022 Createsequence
主题 — NexT.Gemini v5.1.4
0%