自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

qq_16500963的博客

单纯的免费分享知识,有些内容也是从别人那里拷贝过来的,所以本人分享的任何内容都可以无条件供他人转载

  • 博客(45)
  • 收藏
  • 关注

原创 JetCache源码解析——API实现

*** 抽象缓存类,提供了缓存的基本实现,支持键值对的存取操作。该类是线程安全的。* @param 键的类型* @param 值的类型*//*** 通知缓存事件监听器。* @param e 缓存事件。*//*** 获取缓存中指定键的值。* @param key 键。* @return CacheGetResult 获取结果,包含值和操作状态。*/@Override// 对于null键,直接返回错误结果。} else {

2024-03-03 22:19:45 1135 1

原创 JetCache源码解析——缓存处理

在Java技术体系中,如果想要在不改变已有代码逻辑的情况下,对已有的函数进行功能增强,一般可以使用两种方式,如AOP(Aspect Oriented Programming),即面向切面编程,以及代理模式,如使用JDK 动态代理或 CGLIB 动态代理。例如Mybatis的源码中同时使用了JDK 动态代理或 CGLIB 动态代理,但是对于Mapper接口是使用JDK动态代理模式。

2024-01-11 22:33:44 2509

原创 SpringMVC源码解析——HTTP请求处理

这个函数是一个公共方法,它调用了其他的方法来处理HTTP请求,并根据处理结果进行相应的操作。如果返回值为null,它会判断请求是否未修改、响应状态是否为null或请求是否已处理,如果满足条件,则设置请求已处理并返回。媒体类型包括在请求映射中指定的可生成媒体类型、能够写入特定返回值的配置转换器的媒体类型,或者所有媒体类型。函数首先从请求中获取可生成媒体类型集合,如果不为空,则直接返回该集合。否则,函数遍历所有消息转换器,判断是否能够写入特定返回值,如果可以,则将支持的媒体类型添加到结果集中。

2024-01-07 15:25:07 1078

原创 JetCache源码解析——配置加载和初始化

JetCache的配置加载主要是在jetcache-autoconfigure模块中完成的,无论是使用内存缓存LinkedHashMap和caffeine,亦或是通过lettuce、redisson和spring-data-redis来操作Redis服务缓存数据,其自动加载配置的操作基本上都是相似的。

2024-01-06 22:59:19 1359

原创 Spring国际化的应用及原理详解

通过Spring国际化,开发者可以将应用程序的文本、标签、消息等资源抽取出来,并使用合适的语言文件进行翻译,使得应用程序能够根据用户的语言偏好自动切换语言。在Spring国际化的实现中,主要涉及到了MessageSource、LocaleResolver等核心组件,它们共同协作,实现了语言切换的功能。如果 ApplicationContext 无法找到任何消息源,则会实例化一个空的 DelegatingMessageSource,以便能够接受对上述方法的调用。如果在指定的本地没有找到消息,则使用默认消息。

2024-01-04 09:13:07 1397

原创 JetCache源码解析——概览

JetCache是一个基于Java的缓存系统封装,提供统一的API和注解来简化缓存的使用。JetCache提供了比SpringCache更加强大的注解,可以原生的支持TTL、两级缓存、分布式自动刷新,还提供了Cache接口用于手工缓存操作。当前有四个实现,RedisCacheTairCache(此部分未在github开源)、(in memory)和一个简易的(in memory),要添加新的实现也是非常简单的。通过统一的API访问Cache系统通过注解实现声明式的方法缓存,支持TTL和两级缓存。

2024-01-02 21:07:49 1363

原创 Redis源码——压缩列表

压缩列表ziplist本质上就是一个字节数组,是Redis为了节约内存而设计的一种线性数据结构,可以包含多个元素,每个元素可以是一个字节数组或一个整数。Redis的有序集合、散列和列表都直接或者间接使用了压缩列表。当有序集合或散列表的元素个数比较少,且元素都是短字符串时,Redis便使用压缩列表作为其底层数据存储结构。列表使用快速链表(quicklist)数据结构存储,而快速链表就是双向链表与压缩列表的组合。例如,使用如下命令创建一个散列键并查看其编码。

2024-01-01 15:51:28 825

原创 SpringMVC源码解析——DispatcherServlet的逻辑处理

DispatcherServlet类相关的结构图如下:其中jakarta.servlet.http.HttpServlet的父类是jakarta.servlet.GenericServlet,实现接口jakarta.servlet.Servlet。其实,关键的三个函数init、service和destroy分别用于控制Servlet的初始化、运行和销毁。在。

2023-12-30 16:37:20 1848

原创 SpringMVC源码解析——DispatcherServlet初始化

Servlet是一个JAVA编写的程序,此程序是基于HTTP协议的,在服务端运行的(如Tomcat),是按照Servlet规范编写的一个JAVA类。主要是处理客户端的请求并将其结果发送到客户端。作为总控制器的派遣servlet通过处理器映射得到处理器后,会轮询处理器适配器模板,查找能够处理当前HTTP请求的处理器适配器的实现,处理器适配器模块根据处理器映射返回的处理器类型,例如简单的适配器类型、注解控制器类型或者远程调用处理器类型,来选择一个适当的处理器适配器的实现,从而适配当前的HTTP请求。

2023-12-29 22:28:53 2068 1

原创 VMware虚拟机网络配置——桥接模式

VM虚拟机配置桥接模式,可以让虚拟机和物理主机一样存在于局域网中,可以和主机相通,和互联网相通,和局域网中其它主机相通。vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)。什么是桥接模式?桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。

2023-12-25 15:46:42 1104

原创 SpringMVC源码解析——ContextLoaderListener

在配置中只允许声明一次ServletContextListener,多次声明会扰乱Spring的执行逻辑,所以这里首先做的就是对此进行验证,在Spring中如果创建WebApplicationContext实例会记录在ServletContext中以方便全局调用,而使用的key就是WebApplicationContext的ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,所以验证的方式就是查看ServletContext实例中是否有对应的Key的属性。否则返回默认的上下文类。

2023-12-24 22:14:08 1213

原创 SpringMVC源码解析——基础篇

Spring MVC是Spring提供的构建Web应用程序的框架,该框架遵循了Servlet规范,负责接收并处理Servelt容器传递的请求,并将响应写回Response。Spring MVC以DispatcherServlet为核心,众多组件如HandlerMapping为辅助,为用户封装了请求映射等底层逻辑,让用户可以更专注与业务逻辑的处理。本文会对Spring MVC整体结构做简单介绍。

2023-12-23 21:06:22 63

原创 Spring源码解析——容器的功能扩展

ApplicationContext和BeanFactory都是用于加载bean的,但是相比之下,ApplicationContext提供了更多的扩展功能,ApplicationContext包含BeanFactory的所有功能,通常建议比BeanFactory优先,除非在一些限制的场合,比如字节长度对内存有很大的影响时。设置了路径是必不可少的步骤,ClassPathXmlApplicationContext中可以将配置文件路径以数组的方式传入,可以对数组进行解析并加载。

2023-12-17 13:15:00 71

原创 Spring源码解析——创建Bean

结合上面的代码发现,主要是调用createBean函数来创建Bean的,该函数是一个类的中心方法,用于创建bean实例,包括填充bean实例,应用后处理器等。否则要进行常规bean的创建。4、依赖处理,在Spring中会有循环依赖的情况,例如当A中有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时如果A和B都是单例,那么Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题。

2023-12-10 11:30:59 213

原创 Spring源码解析——加载Bean

结合上面的代码发现,主要是调用createBean函数来创建Bean的,该函数是一个类的中心方法,用于创建bean实例,包括填充bean实例,应用后处理器等。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等Bean创建完成就会将创建Bean的ObjectFactory提前加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean,则直接使用ObjectFactory。最后,根据是否为单例对象,在缓存中存储对象。

2023-12-07 23:24:20 92

原创 Redis源码——压缩列表

压缩列表ziplist本质上就是一个字节数组,是Redis为了节约内存而设计的一种线性数据结构,可以包含多个元素,每个元素可以是一个字节数组或一个整数。Redis的有序集合、散列和列表都直接或者间接使用了压缩列表。当有序集合或散列表的元素个数比较少,且元素都是短字符串时,Redis便使用压缩列表作为其底层数据存储结构。列表使用快速链表(quicklist)数据结构存储,而快速链表就是双向链表与压缩列表的组合。例如,使用如下命令创建一个散列键并查看其编码。

2023-11-23 00:18:06 68

原创 Redis源码——跳跃表

在了解跳跃表之前,我们先了解一下有序链表。有序链表是所有元素以递增或递减方式有序排列的数据结构,其中每个节点都有指向下个节点的next指针,最后一个节点的next指针指向NULL。递增有序链表举例如下图所示。如上图所示的有序链表,如果要查询值为51的元素,需要从第一个元素开始依次向后查找、比较才可以找到,查找顺序为1→11→21→31→41→51,共6次比较,时间复杂度为O(N)。

2023-11-19 15:26:34 103

原创 Redis源码——简单动态字符串

SDS既然是字符串,那么首先需要一个字符串指针;

2023-11-19 13:49:36 100

原创 超级有用的c++库

C++ 标准库——包括 STL Containers、STL Algorithm、STL Functional等。C++ 标准库- 类和函数的集合,它们是用核心语言编写的,也是 C++ ISO 标准本身的一部分。标准模板库- 标准模板库 (STL)。C POSIX library - POSIX 系统的 C 标准库规范。ISO C++ 标准委员会- ISO/IEC JTC1/SC22/WG21 - C++ 标准委员会。网站GNU C 库- 本手册的目的是告诉您如何使用 GNU C 库的工具。

2023-11-09 09:50:28 2012

原创 MyBatis——级联映射与懒加载

MyBatis其中一个比较强大的功能是支持查询结果级联映射。使用MyBatis级联映射,我们可以很轻松地实现一对多、一对一或者多对多关联查询,甚至可以利用MyBatis提供的级联映射实现懒加载。所谓的懒加载,就是当我们在一个实体对象中关联其他实体对象时,如果不需要获取被关联的实体对象,则不需要为被关联的实体执行额外的查询操作,仅当调用当前实体的Getter方法获取被关联实体对象时,才会执行一次额外的查询操作。通过这种方式在一定程度上能够减轻数据库的压力。

2023-11-05 11:35:14 222

原创 Mybatisplus源码解析——分页插件

必须要确保自定义的Mapper接口继承Mybatis-plus的BaseMapper接口,然后才能调用BaseMapper的分页函数。实例时传的是MapperMethod对象实例,而在mybatis-plus中传的是MybatisMapperMethod实例,两者在逻辑上差异不大,主要是在execute()函数中。,MyBatis中通过MapperProxy类实现动态代理,在Mybatis-plus中,也使用MapperProxy类实现动态代理的。

2023-10-28 18:43:39 1226

原创 MyBatis——插件原理及应用

MyBatis框架允许用户通过自定义拦截器的方式改变SQL的执行行为,例如在SQL执行时追加SQL分页语法,从而达到简化分页查询的目的。用户自定义的拦截器也被称为MyBatis插件,本章我们就来分析一下MyBatis插件的实现原理以及如何开发一个插件。

2023-10-24 22:53:25 426

原创 Spring Cloud——概述

Spring Cloud为开发人员提供了工具来快速构建分布式系统中的一些常见模式(如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态)。微服务的出现有助于开发人员用更低的成本和更少的错误来开发程序,因此成为Java开发人员需要掌握的最重要的技术之一。Spring Cloud是Spring旗下的项目之一,Spring擅长的就是集成,把世界上的好框架“拿”过来,集成到自己的项目中。Spring Cloud的官方简介如下图所示。

2023-10-23 18:01:11 50

原创 MyBatis源码解析——动态SQL实现原理

如果读者有过JDBC编程经验,肯定能体会到SQL语句拼接的痛苦。在有些情况下,我们需要根据不同的查询条件动态地拼接SQL语句,拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号,这个过程非常容易出错,导致我们需要在调试SQL语句的正确性上花费一定的时间。MyBatis的动态SQL特性能够彻底解决我们的烦恼,本章我们就来学习MyBatis动态SQL的使用及它的实现原理。

2023-10-22 22:44:19 657

原创 MyBatis源码解析——MyBatis缓存

缓存是MyBatis中非常重要的特性。在应用程序和数据库都是单节点的情况下,合理使用缓存能够减少数据库IO,显著提升系统性能。但是在分布式环境下,如果使用不当,则可能会带来数据一致性问题。MyBatis提供了一级缓存和二级缓存,其中一级缓存基于SqlSession实现,而二级缓存基于Mapper实现。本章我们就来学习一下MyBatis缓存的使用,并分析MyBatis缓存的实现原理。

2023-10-20 18:04:20 189

原创 计算机网络知识点全面总结

协议表明IP数据所携带的具体数据是什么协议的,如TCP、UDP。开放最短路径优先协议 OSPF(Open Shortest Path First)【网络层】,基于链路状态的路由选择算法(即Dijkstra算法),较大规模的AS ,适合大型网络,直接封装在IP数据报传输。网络层中涉及众多的协议,其中包括最重要的协议,也是TCP/IP的核心协议——IP协议。传输层的任务是根据通信子网的特性,最佳的利用网络资源,为两个端系统的会话层之间,提供建立、维护和取消传输连接的功能,负责端到端的可靠数据传输。

2023-10-20 11:00:57 69

原创 MyBatis源码解析——SqlSession执行Mapper过程

Mapper由两部分组成,分别为Mapper接口和通过注解或者XML文件配置的SQL语句。为了让读者有一个清晰的思路,笔者将SqlSession执行Mapper过程拆解为4部分介绍:首先介绍Mapper接口的注册过程,然后介绍MappedStatement对象的注册过程,接着介绍Mapper方法的调用过程,最后介绍SqlSession执行Mapper的过程。

2023-10-19 23:01:06 795

原创 高效网络通信技术揭秘,Socket原理与实践

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。TCP/IP协议存在于OS中,网络服务通过OS提供,在OS中增加支持TCP/IP的系统调用——Berkeley套接字,如Socket,Connect,Send,Recv等UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。

2023-10-17 13:22:01 77

原创 MySQL——索引背后的数据结构及算法原理

前两天经历找工作去面试,数据库索引是一大热点,考察比较频繁,所以搜集相关资料学习,这基本是我找到比较详细的文章了,故移于此和大家共享。本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题。特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等。为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引,至于哈希索引和全文索引本文暂不讨论。

2023-10-17 10:02:14 59

原创 MyBatis核心组件

Mybatis分层框架图MyBatis的执行流程及核心组件如下图所示。了解了MyBatis的核心组件后,我们再来了解一下使用MyBatis操作数据库的过程。实际上SqlSession是Executor组件的外观,目的是为用户提供更友好的数据库操作接口,这是设计模式中外观模式的典型应用。真正执行SQL操作的是Executor组件,Executor可以理解为SQL执行器,它会使用StatementHandler组件对JDBC的Statement对象进行操作。

2023-10-15 15:23:09 277

原创 JVM G1源码分析——线程中的安全点

从上面的日志来看这是一个非常正常的例子。但是实际中这一步也有可能花费很多的时间,下面对这一部分内容做一下总结。·前面提到不同的线程进入安全点的时间可能各不相同,特别在编译线程中,如果有一个超级大的循环,假设在JIT编译中没有在循环中插入安全点,那么循环可能一直执行,导致有编译的线程一直不能进入到安全点。JDK 9中引入新的参数UseCountedLoopSafepoints,可打开该参数,允许在循环中插入安全点。

2023-10-13 22:17:09 272

原创 JVM G1源码分析——字符串去重

字符串是我们日常开发使用最多的类型。字符串去重目的是优化字符串对象的内存使用,因为从统计数据上看,应用程序中的String对象会消耗大量的内存。这里面有一部分是冗余的,即同样的字符串会存在多个不同的实例(a!=b,但a.equals(b))。最初JDK提供了一个String.intern()方法来解决字符串冗余的问题。这个方法的缺点在于你必须去找出哪些字符串需要进行驻留(interned)。如果使用得当的话,字符串驻留会是一个非常有效地节省内存的工具,它让你可以重用整个字符串对象。

2023-10-11 23:00:58 327

原创 JVM G1源码分析——引用

我们这里所说的引用主要指:软引用、弱引用和虚引用。另外值得一提的是Java中的Finalize也是通过引用实现的,JDK定义了一种新的引用类型FinalReference,这个类型的处理和其他三种引用都稍有不同。另外在非公开的JDK包中还有一个sun.misc.cleaner,通常用它来释放非堆内存资源,它在JVM内部也是用一个CleanerReference实现。要理解引用处理需要先从Java代码入手。// Reference指向的对象。

2023-10-09 13:28:03 178

原创 Spring整体架构

Spring是于2003年兴起的一个轻量级的Java开源框架,由Rod Johnson在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。Spring是为了解决企业应用开发的复杂性而创建的,它使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。

2023-10-02 15:51:52 37

原创 JVM G1源码分析——Full GC

当对象分配失败,会进入到Evac失败过程,在GC日志详情中会打印相关信息。本章主要介绍:Evac失败后的处理过程,Java 10之前的串行FGC以及Java 10引入的并行FGC。

2023-10-01 11:10:13 394

原创 JVM G1源码分析——混合回收

在介绍新生代回收的时候我们提到,新生代回收会收集所有的YHR;而本章介绍的混合回收(Mixed GC,也称为混合GC)既收集YHR也收集OHR。因为涉及老生代的回收,通常来说老生代的空间比较大,收集老生代可能会花费更多的时间。所以涉及老生代的混合收集算法也不同于新生代回收算法,最明显的是引入并发标记,这里的并发标记指的是标记工作线程可以和Mutator同时运行,当然并发标记引入了复杂度。

2023-09-28 18:29:40 453

原创 JVM G1源码分析——新生代回收

YGC算法主要分为两部分:并行部分和其他部分。我们根据YGC的执行顺序来看一下整个收集过程的主要步骤。1)进行收集之前需要STW。2)选择要收集的CSet,对于YGC来说整个新生代分区就是CSet。根扫描并处理;处理过程会把根直接引用的对象复制到新的Survivor区,然后把被引用对象的field入栈等待后续的复制处理。处理老生代分区到新生代分区的引用;

2023-09-24 22:04:55 605

原创 JVM G1源码分析——Refine线程

对于处理DirtyCard的Refine线程有两个关注点:Mutator如何把引用对象放入到DCQS供Refine线程处理,以及当Refine线程太忙的话Mutator如何帮助线程。我们先介绍比较独立的抽样线程,再介绍一般的Refine线程。

2023-09-22 20:13:18 555

原创 JVM G1源码分析——记忆集(RSet)

同时,除了新生代的回收是需要选择所有新生代的region,老年代的回收,是需要找性价比高的region来回收的,也就是选择一部分去回收,那么选择一部分回收的时候,还要去整个分代对应的这么一大块儿引用关系数据,去做遍历,筛选,才能拿到需要的数据。针对region这个维度,是因为,每次回收之后,老年代,新生代,大对象区域的region可能都会变化,所以,如果说,对每个分代都搞一份儿的话,不太合理,因为region不断的在变化,同时也会有并发问题,效率问题。当新生代的对象被老年代引用,则此对象就不能回收。

2023-09-21 22:05:39 1025

原创 JVM G1源码分析——慢速分配

当不能进行快速分配,就进入到慢速分配。实际上在TLAB中也有可能进入到慢速分配,就是我们前面提到的attempt_allocation,前面已经解释过。这里的慢速分配是指在TLAB中经过努力分配还不能成功,再次进入慢速分配,我们来看一下这个更慢的慢速分配:·attempt_allocation尝试进行对象分配,如果成功则返回。值得注意的是在attempt_allocation里面可能会进行垃圾回收,这里的垃圾回收是指增量的垃圾回收,主要是新生代或者混合收集。大对象分配和TLAB中的慢速分配基本类似。

2023-09-18 13:13:45 226

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除