自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

卓立的博客

Java技术分享

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

原创 Java编程拾遗『AQS』

上篇文章讲了Java中显式锁Lock和ReadWriteLock的概念及简单使用示例,本篇文章重点来看一下Java中显式锁的底层实现。在看这部分代码时,我任务比较好理解的方式是带着问题去看源码。对于显式锁,我们可能会有以下问题:问题1:显式锁底层是基于CAS实现,细节是怎样的? 问题2:显式锁跟synchronized类似,无法获取锁时,会阻塞当前线程,如何实现阻塞的? 问题3:显式锁提供...

2019-08-16 07:19:59 209

原创 理解Https

之前的文章讲golang webSocket编程的文章中提到过Http协议的概念,通过之前的了解我们也知道Http协议其实就是基于传输层的TCP协议和网络层的IP协议实现的一个协议,所以他拥有TCP/IP的所有特性。也正是因为它使用TCP/IP协议,导致它会有以下问题:通信使用明文,通信内容有可能会被窃听 不验证通信方的身份,有可能遭遇伪装 通信内容可能遭到篡改1. HTTP存在的风险...

2019-08-16 07:10:32 283 2

原创 了解Cookie、Session和Token

在Web刚兴起的阶段,Web服务都是静态服务,一般处理前端请求,只需要将相应的html、图片等文件传送到前端即可,这个时候,对于同一个请求,每个用户看到的内容都是完全一样的,服务器也没必要针对不同用户做不同的处理。Http协议最开始就是定义服务器和客户端传送超文本文件的协议,从起源上看,Http协议就是无状态的。但是随着交互式Web应用的兴起,之前无状态的Http协议就不能满足了。比如购物、论...

2019-08-15 07:27:43 268

原创 redis实现分布式锁

分布式锁一般有三种实现方式:Zookeeper Redis 数据库排他锁从可靠性和实现的复杂度讲,上面三种方式在可靠性上逐渐降低,在实现复杂度上也是逐渐降低的。在实际使用中,通过redis实现分布式锁是一种比较常见的方式,但是在使用redis实现分布式锁时,有些不正确的实现往往会导致死锁,错误等问题。本篇文章就来讲解一下redis实现分布式锁的常见方式,及redis分布式锁的正确打开方式...

2019-08-15 07:26:12 226

原创 Spring MVC源码解读『Idea如何构建Spring MVC应用』

从工作几乎一直在使用开箱即用的Spring Boot,很少使用Spring MVC。在上篇文章介绍Spring MVC示例中搭建那个HelloWorld demo过程中,还费了一些周折。想着可能很多人的Java Web之旅都是从Spring Boot开启的,本篇文章我们就来介绍一下如何使用Idea构建Spring MVC应用,以及通过Idea部署Spring MVC应用。1. Idea构建并部署Spring MVC应用1.1 创建Web应用这里我们来看一个最简单的问题,如何通过Idea构建并部署

2020-12-21 07:36:21 597 1

原创 Spring MVC源码解读『Spring MVC示例』

前面几篇文章,我们介绍了Servlet和Tomcat的工作原理。我们之前也说到Spring MVC底层其实也是Servlet,也需要TomcatWeb容器配合才能工作,本篇文章开始,我们就来介绍探索一下Spring MVC的相关细节。本篇文章个先来回顾一下Spring MVC的用法。1. 什么是MVC相信所有的开发人员都避免不了接触一个概念——MVC,这个概念是个比较抽象的概念,也没有没有官方权威定义,全凭我们开发人员自己理解。我一度感觉自己对MVC已经了解地很清楚了,但是在写本篇文章,打算来介绍M

2020-12-21 07:36:04 534 1

原创 Tomcat源码解读『Tomcat类加载机制』

本篇文章我们来探索一下Tomcat的类加载机制,如果我们搜Tomcat的类加载机制,绝大多数结果都会给出答案——打破双亲委托机制。但是感觉很多文章介绍的都不是很清楚,所以本篇文章就从我的理解上来分析一下Tomcat的类加载机制,希望能讲的明白。关于JVM类加载机制,我们在之前的文章Java编程拾遗『Java ClassLoader工作机制』已经介绍过,有兴趣的可以去了解一下。1. Tomcat类加载机制要考虑的问题Tomcat作为Servlet容器,它负责加载我们的Servlet类,此外它还负.

2020-12-21 07:35:45 1311 2

原创 Tomcat源码解读『Tomcat是如何处理web请求的』

之前的四篇文章,我们介绍了Tomcat启动过程的实现:Tomcat源码解读『Tomcat是怎么启动的』 Tomcat源码解读『server.xml解析』 Tomcat源码解读『Context如何构建的』 Tomcat源码解读『web.xml解析』我们知道,Tomcat启动之后,就可以响应来自客户端的web请求了,本篇文章我们来看一下Tomcat容器是如何响应web请求的。1. Servlet是如何生效的做过Java Web的我们都知道,我们的具体业务处理逻辑是卸载Servlet中的,不难

2020-12-19 11:19:35 670 1

原创 Tomcat源码解读『web.xml解析』

上篇文章我们介绍了Tomcat Context是如何构建的,了解了Context构建的两种方式:Host启动,触发HostConfig的Lifecycle.START_EVENT事件监听,构建Context 后台线程,定期去执行Host的backgroundProcess方法,触发HostConfig的Lifecycle.PERIODIC_EVENT事件监听,构建Context这里的构建Context,指的是构建一个Context对象,并将构建好的Context对象与Host组件关联起来(调用hos

2020-12-19 11:17:36 1258 1

原创 Tomcat源码解读『Context如何构建的』

上一篇文章我们介绍了server.xml是如何解析的,其中在介绍Context解析时,提到,多数情况下,并不需要在server.xml中配置Context,而是由HostConfig自动扫描部署目录,以context.xml文件为基础进行解析创建(如果通过IDE启动Tomcat并部署应用,其Context配置将会被动态更新到server.xml中)。所以大多数情况下,Context并不会在server.xml解析时构建出来。那么Context是如何构建出来的?本篇文章就来探索一下Tomcat Conte

2020-12-19 11:15:04 395 1

原创 Tomcat源码解读『server.xml解析』

上篇文章我们介绍到,在Catalina的load方法中,完成了server.xml的解析,将server.xml配置的Server、Service、Connector、Engine、Host各组件实例化,并维护父子级关系。本篇文章我们来看一下server.xml是如何解析的。不难看到,parseServerXml方法执行后,各Tomcat组件就已经生成了。1. parseServerXml核心的解析逻辑就在上图38~49行:Digester digester = start ? c

2020-12-19 11:13:22 724 1

原创 Tomcat源码解读『Tomcat是怎么启动的』

上篇文章我们介绍了Tomcat的核心组件的的基本功能以及在Tomcat中的实现,但是这些组件类是如何被启动起来的?比如我们知道Context组件的功能是管理子容器Wraper的生命周期,那么在Context组件启动时,肯定要创建Wrapper实例并启动Wrapper。同理,我们知道Tomcat这么多组件,肯定有一个先后的启动过程(因为Tomcat的组件本来就是分层级的)。本篇文章我们就来介绍一下,Tomcat是怎么启动的。使用过Tomcat的我们都知道,可以通过Tomcat的/bin目录下的脚本star

2020-12-19 11:12:11 431 1

原创 Tomcat源码解读『基础类介绍』

通过之前两篇关于Tomcat的介绍,我们已经清楚知道Tomcat的作用及基本的工作原理。本篇文章开始,我们来从解读Tomcat源码。本篇先来介绍一下Tomcat的基础类,以便我们后续介绍Tomcat启动流程,工作流程。我们知道,Tomcat的能作为web容器正常工作,依赖于Server.xml配置文件,如下:<?xml version="1.0" encoding="UTF-8"?><Server port="8005" shutdown="SHUTDOWN"> &l

2020-12-19 11:10:59 509 1

原创 Tomcat系统架构

上篇文章,我们自定义实现了一个简单的不能再简单的Tomcat容器,大致了解了Tomcat的工作主要功能。本篇文章我们就来看一下正主——Tomcat,每一个从事Java Web开发的都需要了解的基础工具。Server:Tomcat顶层容器,可以包含一个或多个Service组件 Service:Server内部的中间组件,包含Connector和Container两个核心组件,负责将一个或多个Connector组件绑定在一个Container上 Connector:用于处理连接相关的事情,并提供So

2020-12-19 11:09:47 410 1

原创 自定义实现一个mini版Tomcat

通过之前的介绍,我们大致了解了Tomcat的基础功能,即为Servlet生效提供环境支持。那么Tomcat肯定需要提供以下基础功能:提供Socket服务:实现对某些端口的监听,从而实现请求到来时,Tomcat可以感知到。同时该Socket服务也需要支持HTTP协议。 封装请求和响应:通过之前的介绍,我们知道在我们开发Servlet时,Web容器已经将Context、Request、Response替我们封装好了,可以直接使用。Tomcat作为一款Servlet容器,肯定要支持这项功能。 请求分发:一

2020-12-19 11:08:32 556 1

原创 Java Web三大组件

上篇文章我们介绍了Servlet和Jsp以及一些Java Web开发的基础概念,本篇文章我们来介绍另一Java Web开发中的重要概念——Java Web三大组件,即Servlet、Filter和Listener。1. Servlet由于我们上篇文章已经介绍过Servlet了,这里就不再详细介绍了,透过现象看本质——什么是servlet。2. FilterFilter(过滤器)用于拦截用户请求,在服务器作出响应前,可以在拦截后修改request和response。可以实现一次编码,多处应用。

2020-12-19 11:05:56 833 1

原创 透过现象看本质——什么是servlet

我们通过几篇文章介绍了Spring的IOC和AOP两大属性,本来打算开始介绍Spring MVC的。但是想了一下,在介绍MVC框架之前,还是应该来缕清MVC底层的本质——Servlet,这个看着“非常久远”的概念,以便我们能更好地了解学习框架。提到Servlet,有很多人可能是有些陌生的,因为在工作中一般很少直接用到Servlet,都是直接上手框架,以至于很容易出现如下两种看法:框架和Servlet割离,认为是两个概念,比如“Servlet还在使用吗” 知道框架和Servlet有关联,但把Serv

2020-12-19 11:03:30 653 2

原创 Spring源码解读『AOP』

之前的文章我们介绍了Spring IOC的相关概念及相应的底层源码实现,本篇文章我们来看一下Spring的另一重要特性AOP的相关细节。1. AOP示例1.1 Bean interfacepackage com.zhuoli.service.spring.explore.aop.bean;public interface AopBean { void method1(); void method2();}1.2 Bean interface实现packag

2020-07-10 07:45:55 256

原创 Spring源码解读『通过配置类启动spring容器』

之前的介绍中,Spring容器都是通过xml配置文件启动的,在实际开发中,xml配置的使用是逐渐减少的,一般在开发中更建议使用Java Config。本篇文章我们就来看一下Spring容器如何通过配置类启动的。Spring提供了AnnotationConfigApplicationContext类,实现通过Java Config配置类来启动Spring容器。1. 示例1.1 定义Beanpublic class TestBeanA { private String testName

2020-07-10 07:45:11 557

原创 Spring源码解读『占位符@Value(“${…}”)替换』

上篇文章介绍了xml配置文件中占位符${…}的解析过程,本片文章我们来继续介绍Spring中另一种占位符@Value(“${…}”),这种占位符一般出现在Java Config中,如下:@Configurationpublic class MyConfiguration { @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String userName;

2020-07-10 07:44:22 6427 1

原创 Spring源码解读『占位符${…}替换』

在使用Spring时,对于一些比较固定的参数,我们一般会采用配置的方式,将这些参数配置在.properties配置文件中,然后在Bean初始化过程中替换为配置文件中配置的真实值。在Spring中,这种典型的的使用会存在以下两种方式:在xml配置中,通过${…}:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:

2020-07-10 07:43:37 5183 1

原创 Spring源码解读『@Configuration配置类』

上篇文章我们介绍了通过xml配置文件来解析Bean配置的过程,本篇文章我们来看另一种解析Bean配置的方式,@Configuration配置类。在Spring应用中,为了使用@Configuration配置类,如果使用xml启动ApplicationContext,我们一般会在xml配置文件中加上如下一行配置:<context:component-scan base-package="com.zhuoli.service.spring.explore.config"/>以告诉Sprin

2020-07-10 07:42:04 518

原创 Spring源码解读『配置文件解析』

之前的文章详细介绍了Bean的实例化和初始化的过程,但其实Bean能实例化、初始化的前提是Spring容器在启动时,间配置文件(配置类)中的配置加载成BeanDefinition,这一点我们再之前的文章Spring源码解读『IOC容器1-自定义实现IOC容器』一文中看得比较清楚。关于Spring对配置文件(配置类)的处理,我们还没有介绍,本篇文章我们就来介绍一下Spring容器启动时是如何加载xml配置文件并加载成BeanDefinition的,在下篇文章来介绍@Configuration配置类。首先来看一

2020-07-10 07:40:06 381

原创 Spring源码解读『Spring Bean循环依赖』

由于Spring的IOC特性,Bean都是由Spring容器生成的,那么如果Bean是单例的,存在两个Bean,分别为beanA、beanB,beanA依赖beanB,同时beanB也依赖beanA,那么可以想象假如容器不做特殊处理的话,就会发生循环依赖,产生死锁,Bean构造就进行不下去了。但是我们在使用时,其实并没有关注循环依赖的问题,Spring是可以解决这种循环依赖的情况的,本篇文章我们来看一下Spring是如何解决循环依赖的。1. Spring循环依赖示例首先定义两个Bean,BeanA和

2020-06-30 08:37:07 281

原创 Spring源码解读『Bean扩展接口』

上篇文章我们介绍了Spring Bean的初始化流程,在最后我们提到在通过populateBean方法调用后,调用了initializeBean方法,实现了一些列例如BeanNameAware、BeanPostProcessor等扩展接口的调用,本篇文章我们就来看一下Spring提供给开发者的一些扩展接口。Spring框架运用了非常多的设计模式,从整体上看,它的设计严格遵循了OCP——开闭原则:对修改关闭,外部无法修改Spring整个运作的流程 对扩展开放,可以通过继承、实现Spring提供的众多

2020-06-30 08:36:29 223

原创 Spring源码解读『IOC容器3-Bean初始化』

上篇文章我们介绍了Spring源码阅读的入口,分析了通过xml配置文件到Spring Bean初始化出来的流程。在上篇文章中,我们讲到,所有非懒加载的bean都是在finishBeanFactoryInitialization方法中完成实例化和初始化。由于该方法是整个Bean加载流程的核心方法,并且介绍起来篇幅较长,所以该方法单独在本篇文章介绍。在阅读源码之前,我们可以简单想象一下该方法的实现内容。在该方法执行之前,所有的Bean配置(通过xml配置文件或者配置类)都已经转变层BeanDefinition并

2020-06-30 08:35:47 270

原创 Spring源码解读『IOC容器2-Bean加载过程』

上篇文章,我们自定义实现了一个简单地IOC容器。本篇文章我们来介绍一下Spring IOC容器的实现。1. 准备工作为了学习Spring的源码实现,我们需要准备Spring的源码环境,这时我们一般可以有以下两种选择:1.1 下载spring-framework git项目将spring-framework git项目下载到本地git clone https://github.com/spring-projects/spring-framework.git将源码导入到Idea中这

2020-06-30 08:34:59 384

原创 Spring源码解读『IOC容器1-自定义实现IOC容器』

上篇文章介绍了Spring的相关基础概念,我们了解到Spring Framework提供的两个基础功能就是IOC和AOP。关于IOC容器我们分为两篇文章来介绍,本篇文章会介绍IOC容器的基础概念,并自定义实现一个基础的IOC容器,帮助我们后续更好的解读IOC源码。AOP会在之后的文章中介绍。1. IOC容器基本概念IOC(Inversion Of Control)也叫控制反转,这个概念经常会伴随另一个概念DI(Dependence Injection)依赖注入出现。直白的讲就是,Java中一个对象依

2020-06-30 08:31:52 579

原创 Spring源码解读『基本概念』

Spring作为一个优秀的开源框架,作为一名服务端开发人员,在工作中必然是每天都要接触的,相信每个人也都能熟练地使用Spring来完成日常工作。毫不夸张的讲,Spring很大程度上改变了Java开发的方式。但是在工作中,我发现很多数人对Spring的了解都停留在表面,很少去深究Spring这一优秀框架底层的原理。结合我自身的体会而言,在刚开始接触这个框架的时候,仅仅是生硬地去记它的一些使用特性,一旦遇到一些“非常规”问题,就搞不定了。随着使用的深入,疑惑的问题越来越多(比如框架给我们带来什么好处?Sprin

2020-06-30 08:31:08 332

原创 使用Netty实现RPC

Netty作为一个异步事件驱动的网络应用框架,可以用于快速开发可维护的高性能服务器和客户端。国内著名的RPC框架Dubbo底层使用的是Netty作为网络通信的。本篇文章我们来探索一下RPC框架的本质以及使用Netty来实现一个简单地RPC框架。1. RPC是什么RPC(Remote Procedure Call),翻译成中文就是远程过程调用。远程过程就是相对于本地方法而言的,是运行在某个远程的地方而不是本地。通过RPC可以实现像本地函数调用一样调用远程服务,是一种进程间的通信方式。RPC调用的本质可

2020-06-30 08:30:15 2938 2

原创 使用Netty实现HTTPS

之前的文章理解Https中,介绍了HTTP到HTTPS的演进过程,我们也可以得到一个结论:HTTPS = HTTP + 加密 + 身份认证 + 报文正确性保障。其实也就是在HTTP层和TCP层之间新增一个步骤,通过证书交换通信秘钥并验证客户端服务端身份的合法性(SSL)。所以为了实现HTTPS,必须支持SSL。为了支持SSL,Java提供了 javax.net.ssl 包,它的SSLContext 和SSLEngine类使得解密和加密相当简单和高效。Netty提供了基于SSLEngine的实现OpenS

2020-06-30 08:29:27 4542

原创 Netty基础组件

之前的文章Netty基础篇:Netty是什么?介绍了传统IO编程存在的问题,及Java NIO编程在解决IO编程的问题中的局限性,由此引出IO编程问题的理想解决方案——Netty。在上篇文章中简单展示了Netty的基本使用,本篇文章通过一个Netty服务端的demo来了解一下Netty的基本组件。1. Netty服务端public class EchoServer { private final int port; public EchoServer(int port) {

2020-06-30 08:27:56 193

原创 Java编程拾遗『JVM垃圾回收』

垃圾收集(Garbage Collection)通常被称为GC,大部分人都把这项技术当作Java语言的伴生产物。事实上,GC的历史远远比Java久远,1960年诞生于MIT的Lisp语言是第一门真正使用内存动态分配和垃圾收集技术的语言。经过半个世纪的发展,内存动态分配与内存回收技术已经相当成熟,一切看起来都进入“自动化”时代,那么为什么我们还要去了解GC和内存分配呢?原因很简单:当需要排查各种内存溢出、内存泄漏问题时,当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这些“自动化”技术实施必要的监控和调

2020-06-30 08:26:36 256

原创 Nginx + Lua开发

之前Nginx那篇文章讲过,我希望通过Nginx做一个测试环境,目标其实很简单,其实就是使用Nginx做反响代理服务器,绕过现在的鉴权系统,将前端请求转发到相应人员的“开发机”上去,其实在过程中遇到几个比较棘手的问题,如下:如何确定相应的前端请求到后端服务映射,即区别前端请求,将需求A的前端请求转发需求A的机器上而不会转到需求B的开发机上 后端服务会对请求体进行SHA-1数据加密校验,将请求...

2020-01-07 07:47:49 1362

原创 Java编程拾遗『JVM内存区域』

作为一名Java开发人员,JVM是我们每天都会打交道的对象。但是由于JVM处于知识体系的底层,同时工作中有可能接触的机会不是很多,导致很多人都对JVM相关的知识一知半解。一般只会在面试的时候,才来准备这部分内容。但JVM是为了让我们更好的理解Java,更深入了解我们每天开发程序的执行机制。所以从本篇文章开始,我们来介绍以下JVM相关的知识。大致规划一下应该会包括 以下内容:JVM内存区域、垃圾...

2020-01-07 07:43:15 200

原创 Java编程拾遗『Java ClassLoaser工作机制』

ClassLoader顾名思义就是类加载器,负责将类的.class文件中的二进制数据加载到JVM中,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构(类的方法代码,变量名,方法名,访问权限,返回值等)。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。类加...

2020-01-07 07:41:48 304

原创 Java编程拾遗『ThreadLocal』

本篇文章,我们来介绍一下,Java多线程编程中一个比较常用的工具,线程本地变量——ThreadLocal。ThreadLocal简单的来讲,就是每个线程都有同一个成员变量的独有拷贝。由于每个线程都有成员变量独立的拷贝,所以不存在多线程访问同一成员变量的问题,也就解决了线程安全问题。之前我们介绍的锁,是解决线程安全问题的一个途径,那么本篇文章介绍的线程本地变量是另一种解决线程安全问题的思想,就是通过...

2020-01-07 07:39:31 209

原创 Java编程拾遗『线程协作工具』

在之前的文章Java编程拾遗『线程协作』中,介绍了一些线程协作的场景,并做了简单的代码实现,比如上文中的MyLatch、AssemblePoint、MySemaphore等。其实上篇文章介绍的线程协作场景,在Java API中都有响应实现。本篇文章就来介绍一下,Java API中提供的一些线程协作工具及使用场景。本篇文章会介绍以下几种协作工具:CountDownLatch CyclicBar...

2020-01-07 07:38:05 212

原创 Java编程拾遗『线程池』

在之前的文章中,我们已经讲了很多Java线程的使用以及Java并发编程的原理,本篇文章,我们来重点看一下Java并发编程中一个比较常用的工具——线程池的使用以及源码实现,这也是Java面试的基本问题。在使用线程池之前,我们可以尝试考虑这样一个问题,如果没有线程池,我们是怎样实现多线程编程的以及实现方式有哪些问题?首先,如果没有线程池,我们一般会直接通过new Thread()构造出多个线程,然...

2020-01-07 07:36:59 214

原创 Java编程拾遗『并发容器——并发队列』

本篇文章,来探讨一下Java并发包中的各种队列。Java并发包提供了丰富的队列类,可以简单分为:无锁非阻塞并发队列:ConcurrentLinkedQueue和ConcurrentLinkedDeque 普通阻塞队列:基于数组的ArrayBlockingQueue,基于链表的LinkedBlockingQueue和LinkedBlockingDeque 优先级阻塞队列:PriorityBl...

2020-01-07 07:34:15 156

空空如也

空空如也

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

TA关注的人

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