自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

CRUD工程师

弱鸡一枚,求大佬轻喷

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

原创 Java内存结构

方法区(Method Area)也被称为永久代。方法区用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版本/字段/方法/接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将类在加载后进入方法区的运行时常量池中存放。OutOfMemoryError 简称为 OOM。

2024-01-09 10:03:07 955

原创 Tomcat源码:CoyoteAdapter、Valve#invoke、ApplicationFilterChain

在前文中,我们介绍了Processor如何接收来自EndPoint的Socket,读取字节流解析成 Tomcat Request 和 Response 对象,最后将请求传递给了Adapter做进一步的处理。本文我们就来介绍下一个请求是如何从连接器被转发到容器中并由相应的servlet处理的。目录前言一、CoyoteAdapter2、service3、invoke二、Valve#invoke1、invoke三、ApplicationFilterChain2、doFilter。

2023-09-11 10:03:17 304

原创 Tomcat源码:SocketProcessor、ConnectionHandler与Http11Processor

前文中我们介绍了Acceptor与Poller,其中Acceptor负责监听socket连接,并将请求转交到Poller中调用processSocket方法处理。结合我们之前介绍连接器时的讲解,EndPoint 接收到 Socket 连接后,生成一个 SocketProcessor 任务提交到线程池去处理,SocketProcessor 的 Run 方法会调用 Processor 组件去解析应用层协议,这一操作的起点就是processSocket方法,下面我们就从该方法开始讲起。

2023-06-02 11:05:47 986

原创 Tomcat源码:Acceptor与Poller、PollerEvent

前文中我们介绍到NioEndpoint的start方法启动了Acceptor与Poller这两个异步线程来处理连接请求,本文我们就来接着介绍这两个组件。目录前言一、Acceptor1、构造方法2、run方法LimitLatchNioChannel二、Poller与PollerEvent2、pollerregisterruneventsprocessKey。

2023-05-25 21:42:03 1454

原创 Tomcat源码:ProtocolHandler与Endpoint

前文中我们介绍了连接器与其入口Connector以及线程池Executor,而在Connector中则是通过protocolHandler的init与start启动了整个连接器,本文我们就来介绍下protocolHandler与其关键组件Endpoint的内容,以及线程池Executor是如何发挥其作用的。目录前言一、ProtocolHandler1、构造方法1.1、Http11NioProtocol与其抽象父类1.2、 AbstractProtocol与成员变量的赋值2、生命周期方法2.1、init方法。

2023-05-19 13:19:19 982

原创 Tomcat源码:连接器与Executor、Connector

在前面得文章中,我们介绍了Tomcat中得容器是如何从service启动到具体得servlet包装类wrapper得。servlet容器启动后就可以为我们提供访问服务了吗?答案是否定得,因为servlet只规定了如何处理请求,但没有实现请求得分发,这个功能是由tomcat得另一部分连接器来完成得。(图片来源《Tomcat连接器》,左侧为连接器,右侧为容器)连接器的启动点为connector组件,在前文《Tomcat源码:StandardServer与StandardService》

2023-05-10 23:00:25 1433

原创 Spring源码:动态代理的增强顺序(AOP与事务的先后)

在之前的文章中,我们介绍了AOP与Spring事务的内容(事务管理也是通过AOP的动态代理实现的),包括代理的创建、执行等,但是遗留了一个问题,那就是多个增强的执行顺序是怎样的,本文我们就来进行下梳理。AOP在被设置在了后置处理器中,每个bean创建完后会判断是否需要创建代理类,如果需要则获取所有的通知方法(包括继承了Advisor接口的实现类与@Aspect标注的切面类中的增强方法,包装为Advisor类)并放入缓存中以便下次代理,然后筛选出适用于当前bean的增强并封装为代理对象。

2023-04-30 17:37:54 1557 2

原创 Tomcat源码:Pipeline与Valve

在前文中,我们介绍了tomcat容器部分中的Engine、Host、Context、Wrapper,截止Wrapper中loadOnStartup=1的servelt启动后整个tomcat的启动就算完成了,不过除了容器tomcat还有连接器的部分,即如何将请求发给对应的servlet来进行处理。连接器的内容我们会在后续的文章中进行介绍。

2023-04-26 21:26:46 801

原创 DDD领域驱动设计入门:1

由于最近接触的新项目采用了DDD领取驱动设计的方式,网上对DDD的讲解文章很多都是偏理论的且很多都倾向于和微服务的结合,对一些朋友不太友好,因此本文计划直接以代码示例的方式来进行讲解,将抽象的概念具体化,让初学者也能快速入门。

2023-04-23 10:39:31 281

原创 Tomcat源码:StandardEngine、StandardHost、StandardContext、StandardWrapper

在前文中,我们介绍了容器组件的公共接口Container接口,这个接口的抽象实现类ContainerBase实现了initInternal、startInternal这两个生命周期,规定了子容器中的大部分行为,本文我们就来继续深入到各个子容器中进行源码的分析。目录前言一、StandardEngine二、StandardHost三、HostConfig生命周期监听器的添加生命周期监听器的执行start与deployAppsdeployWARs四、StandardContext触发事件监听器。

2023-04-16 14:12:24 629

原创 Tomcat源码:Container接口

前文中我们介绍了StandServer与StandService的init与start方法,本文我们接着介绍以Engine为首的子容器。由下图可以看出Engine、Host、Context、Wrapper等容器组件都继承了Container接口,从而间接继承了Lifecycle接口,而其抽象实现类ContainerBase又继承了LifecycleMBeanBase类,本文我们就介绍下Container这个接口。目录前言一、Container接口1、父子容器交互2、事件监听。

2023-04-11 12:59:28 750

原创 Tomcat源码:StandardServer与StandardService

在前文中我们介绍了tomcat启动类的加载,在Catalina初始化时加载了server.xml,并调用了getServer().init()方法加载server接口的实现类standserver。另外还介绍了以standserver为代表的容器组件共同继承的用于管理生命周期的抽象类LifecycleBase。本文我们接着前文的内容继续介绍standserver与standservice。目录前言一、StandardServer1、init2、Start二、StandService1、init。

2023-04-09 12:33:37 461

原创 Tomcat源码:容器的生命周期管理与事件监听

在前文中我们介绍了tomcat的启动类加载,最后介绍到了getServer().init(),这里的getServer()就是获取加载server.xml时创建的StandardServer对象,StandardServer对象即server接口的实现。

2023-04-08 17:34:46 620

原创 Spring事务源码:事务的提交与回滚

在前文中,我们介绍了事务的创建,事务创建好后就可以执行被代理方法了,执行完后我们还需要根据其执行结果判断是提交还是回滚,本文我们就来深入讲解下这两个操作。// 声明式事务处理// 创建事务,事务属性等信息会被保存进TransactionInfo中try {// 执行目标方法// 异常处理throw ex;finally {// 清空事务信息// 提交事务目录前言一、事务回滚2、rollback二、事务提交2、commit4、doCommit三、清除事务信息。

2023-04-06 09:08:35 1570

原创 Spring事务源码:事务创建

在前文中我们介绍了Spring事务管理是如何开启以及创建代理类对象的,本文我们来深入解析下代理类是如何实现事务的管控。目录前言一、代理类中方法执行二、事务管理三、开启事务1、获取当前事务2、获取事务对象3、判断是否存在事务4、挂起事务5、开启新事务6、绑定线程与数据库连接7、创建默认status8、存在原事务时的处理方案。

2023-04-04 09:16:22 830

原创 Spring事务源码:创建代理类

本文我们介绍下Spring中的事务管理的源码,Spring的事务管理主要有申明式事务与编程式事务这两种,如果对这两种方式不了解的朋友可以先看下这篇文章(《Spring事务管理(详解+实例)》)然后再来深入源码分析。我们通过如下方式开启事务,由于申明式事务的注入方式式基于代理方式实现的,因此这里也建议先了解下AOP的源码,这部分我前文已经做了完整的介绍,因此下文将不会对AOP的功能做深入的解析,有需要的朋友可以看下我之前AOP的文章。目录前言。

2023-04-01 17:17:20 776

原创 RabbitMQ:Exchange交换器的不同模式

在此前的文章中,介绍了AMQP协议,而rabbitmq正是该协议的实现,本文我们就来介绍下rabbitmq中的Exchange模型。(建议先学习下rabbitmq的Hello World样例《RabbitMQ(一):Hello World程序》,明确生产者、消费者、队列以及交换机的概念及关系)目录前言一、Fanout1、定义2、样例二、Direct1、定义2、样例三、Topic1、定义2、样例Fanout模式即广播,每个发到fanout类型交换器的消息都会分到所有绑定队列上去。

2023-03-26 17:26:48 330

原创 Tomcat源码:启动类Bootstrap与Catalina的加载

本文开始我们将会介绍tomcat的源码,整个流程会按照tomcat的启动顺序来开展,在此之前建议先阅读下前文理清servlet与servlet容器之间的关系。传送门在tomcat的bin目录下有两个启动tomcat的文件, 一个是startup.bat, 它用于windows环境下启动tomcat;另一个是startup.sh, 它用于linux环境下tomcat的启动. 两个文件中的逻辑是一样的, 我们只分析其中的startup.bat。

2023-03-22 09:18:31 963

原创 SpringMVC源码:视图解析与异常处理

抽象类AbstractView执行对数据进行组装,输出操作交由子类完成@Override// 组装数据// 渲染输出AbstractHandlerExceptionResolver对接口进行了一个抽象,实现其中的通用逻辑,并暴露对应的doResolveException方法交由子类实现。@Override//先判断该异常处理类是否支持处理handler执行过程中产生的异常//设置response禁用缓存 使用preventResponseCaching(默认是false不禁用缓存)

2023-03-12 12:09:09 648

原创 SpringMVC源码:视图解析器

过程和HandlerMapping的初始化很类似,一样是解析容器中的ViewResolver类型的Bean。if (!else {try {该方法可以对解析过的视图对象进行缓存,下面我们看下其实现原理@Override@Override// 默认1024@Override//判断是否对解析出来的View对象(视图对象) 进行缓存//判断逻辑是其cacheLimit(允许缓存的视图对象个数)默认是1024 默认是走缓存 可以更改为不走缓存if (!//创建View。

2023-03-09 08:57:27 961

原创 SpringMVC源码:参数解析、方法调用与返回值处理

这里以AbstractHandlerMethodAdapter类为例,可以看到内部实际上是调用了handleInternal方法,而这个方法实际上是由子类RequestMappingHandlerAdapter实现的。(注意下这里的返回值为ModelAndView)@Override。

2023-03-06 14:15:00 881

原创 SpringMVC源码:getHandler、getHandlerAdapter过程

这里的主要作用是根据请求获取包装了Handler对象和拦截器的HandlerExecutionChain对象。该方法采用模板方法获取拦截器处理器链。@Override//交由子类实现的根据请求获取处理器的具体逻辑 不同的子类获取Handler的逻辑不同//如果没有获取到Handler 则获取默认的Handler//默认的处理器可以通过配置映射器实例的时候通过属性设置//如果默认的Handler还是没有则返回空//Handler处理器是字符串类型 说明获取的Handler是beanName。

2023-03-04 14:17:22 713

原创 SpringMVC源码:HandlerMapping加载2

但是在我们的日常开发中,handler大部分是一个使用@RequestParam修饰的一个方法,比如这样。

2023-03-02 10:06:54 388

原创 SpringMVC源码:HandlerMapping加载1

AbstractHandlerMapping是HandlerMapping的抽象实现,同时实现了Order接口继承了WebApplicationObjectSupport类,order接口主要是为了如果spring容器中有多个HandlerMapping,则按照order 排序去一次使用HandlerMapping获取handler对象,order小的优先被使用。

2023-02-28 08:56:47 421

原创 SpringMVC源码:DispatcherServlet初始化流程

MVC结构我们都知道,将模型、视图与控制器拆分实现分层。SrpingMVC采用类似的结构。不同的地方在于,SpringMVC的控制器多了一个,即前端控制器。前端控制器的作用在于将不同的请求根据地址转给不同的控制器进行处理,并对返回的模型选择相应的视图进行渲染。

2023-02-26 11:13:40 986

原创 设计模式:行为型设计模式

行为型模式是将不同的行为代码解耦,从而解决特定场景问题的一些经典结构。行为型设计模式主要解决的就是“类或对象之间的交互”问题。行为型设计模式比较多,有 11 个,几乎占了 23 种经典设计模式的一半。它们分别是:观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式。只定义一个方法过程中的主要过程,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,这就是模板模式。

2023-02-18 09:45:04 541

原创 JMS规范和AMQP协议

JMS(JAVA Message Service,Java 消息服务)是一个Java平台中关于面向消息中间件的API,由Sun公司早期提出,旨在为java应用提供统一的消息操作。JMS允许应用程序组件基于 JavaEE 平台创建、发送、接收和读取消息,即JMS 的客户端之间可以通过 JMS 服务进行异步的消息传输。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。ActiveMQ 就是基于 JMS 规范实现的。

2023-01-08 09:00:00 551

原创 Java8之JMX与MBean

Dynamic MBean必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义。另外还有两类 MBean:Open MBean 和 Model MBean,实际上它们也都是动态 MBean。

2022-12-18 16:00:17 1698

原创 Java8:SPI机制

SPI(Service Provider Interface)是JDK内置的一种 服务提供发现机制,可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用。比如java.sql.Driver接口,不同厂商可以针对同一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而Java的SPI机制可以为某个接口寻找服务实现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。

2022-12-11 13:04:26 663

原创 性能优化:Redis使用优化(2)

参考资料:《Redis,该如何监控》《Redis为什么变慢了?一文讲透如何排查Redis性能问题 | 万字长文》相关文章:《Redis:内存淘汰机制》《Redis:持久化RDB与AOF》《Redis:主从复制》 《性能优化:Redis使用优化(1)》 写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。 上文中,我们介绍了Redis使用过程中操作命令、内存使用的注意事项,本文我们会继续介绍其余的相关注意事项。目录前言一、硬件使用优化 1、绑定

2022-12-08 11:42:21 448

原创 性能优化:Redis使用优化(1)

参考资料:《Redis为什么变慢了?一文讲透如何排查Redis性能问题 | 万字长文》相关文章:《Redis:内存淘汰机制》《Redis:持久化RDB与AOF》《Redis:主从复制》 写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。 在之前的文章中,我们介绍了redis的内部结构、使用方法等,这篇文章就来讲讲我们如何优化redis的使用。 深入理解本文需要对redis的相关内容有足够的了解,如果不熟悉的朋友可以先从我之前的文章开始看起(

2022-12-06 11:29:53 429

原创 性能优化:Netty连接参数优化

在此前的文章中我们介绍了Netty这一网络编程框架,既然是网络编程,那就必然与网络连接有非常密切的联系。而Netty为了能更好的使用网络连接,提供了一些参数来对网络连接进行设置。在客户端,可以使用Bootstrap.option()函数来配置参数,配置参数作用于SocketChannel。在服务器端,可以使用ServerBootstrap来配置参数,但是对于不同的 Channel 需要选择不同的方法。

2022-12-04 15:35:59 688

原创 Tomcat:servlet与servlet容器

在介绍Tomcat之前,我们首先需要了解它的作用,简单的说,tomcat就是一个servlet容器。因此,本文首先从Web 应用程序开始讲起,逐步介绍servlet。Web即表示网页的意思,它用于表示 Internet 主机上供外界访问的资源。Web 应用程序是一种可以通过 Web 访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。静态 web 资源:指 web 页面中供人们浏览的数据始终是不变。

2022-11-30 09:22:41 1364

原创 java8:关闭钩子shutdown hook

在Java程序退出时,我们可能需要先执行一些善后工作,如关闭线程池、连接池、文件句柄等,即所谓“优雅停机”(graceful shutdown)。如何保证善后工作的代码能够被执行到呢?Java为用户提供了关闭钩子(shutdown hook)。这些钩子可以在应用关闭时帮助我们完成JVM退出前的善后工作,例如删除临时文件,或者清除无法由操作系统自动清除的资源。程序正常退出,即最后一个非守护线程结束时;程序中执行到了System.exit()方法;终端接收到了CTRL-C中断,或者注销登录;

2022-11-28 09:09:29 1511

原创 Netty:粘包与半包的处理

先看如下代码,这个代码是使用netty在client端重复写100次数据给server端,ByteBuf是netty的一个字节容器,里面存放是的需要发送的数据。i < 1000;i++) {}}byte[] bytes = "你好,我的名字是1234567!}}从client端读取到的数据为:从服务端的控制台输出可以看出,存在三种类型的输出一种是正常的字符串输出。一种是多个字符串“粘”在了一起,我们定义这种 ByteBuf 为粘包。

2022-11-26 09:59:13 179

原创 Netty:入门(2)

在前文中,我们对Netty的内容做了简单的介绍,本文我们会结合Netty的流程图相对深入一些的介绍下其中的重要组件。

2022-11-20 12:52:36 675

原创 性能优化:MySQL使用优化(3)

在之前的文章中,我们介绍了就基于sql的调整的优化,这篇文章我们将会结合之前的文章解释下如何基于mysql的配置进行优化。深入理解本文需要对MySQL的内部结构(三大日志体系:undo log、redo log、bin log,buffer pool)有基本的了解,如果不熟悉的朋友可以先从我之前的文章开始看起(《MySQL:基础架构与存储引擎》《MySQL:更新过程(buffer pool与redo、bin、undo log)》)。目录前言一、连接配置1、连接数配置2、超时配置二、数据库数据交换配置。

2022-11-15 11:07:24 329 1

原创 Netty:入门(1)

在此前的文章中,我们已经对NIO等内容做了基本介绍,但是java NIO类库和API繁杂,学习成本高,还需要熟悉Java多线程编程才能写出高质量的NIO程序。因此便有了封装好的网络编程框架Netty。(建议在阅读本文前先了解完《IO 模型与多路复用》)。目录前言一、线程模型1、传统阻塞IO线程模2、Reactor模型2.1、单 Reactor 单进程 / 线程2.2、单 Reactor 多线程 / 多进程2.3、多 Reactor 多进程 / 线程二、Netty的基本介绍1、Netty是什么。

2022-11-06 15:24:45 275

原创 性能优化:MySQL使用优化(2)

在前文中,我们介绍了索引使用的注意点和失效场景以及分析方法,这篇文章我们来继续介绍下MySQL本身的优化以及我们如何调整语句本身来优化。目录前言一、MySQL自身进行的优化1、覆盖索引2、索引下推3、MRR(Multi-Range Read)机制4、Index Skip Scan索引跳跃式扫描5、Filesort的优化5.1、两次扫描算法5.2、一次扫描算法二、SQL使用优化优化方案2.1、添加索引2.2、加上order by null 禁止排序3、子查询与连接3.1、子查询优化3.2、连接代替子查询。

2022-10-31 08:45:00 204

原创 性能优化:MySQL使用优化(1)

在MySQL专栏之前的文章中,我们介绍了MySQL的主从复制与高可用架构MHA等,这些都是架构层面的MySQL优化方案(包括还在计划中的分库分表),今天我们再重新从最基础的SQL使用的角度去看如何优化我们的SQL。SQL本身的优化主要是两种情况,一种是项目开发阶段的表相关的设计,另一种是项目上线后针对暴露出的问题进行优化。前一种情况需要设计好表的字段、索引,需要遵循哪些范式,是否需要冗余一些字段来减轻表连接的频率,后一种情况则需要统计慢SQL(对于慢SQL的统计与分析可以看我的这篇文章。

2022-10-30 15:23:41 426

空空如也

空空如也

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

TA关注的人

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