自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(171)
  • 收藏
  • 关注

原创 软件设计原则 —— 迪米特原则和合成复用原则

迪米特法则(Law of Demeter)又叫作最少知识原则(Least Knowledge Principle 简写LKP),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话。(百度百科)迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则

2020-10-28 11:38:57 452

原创 Java核心基础之异常处理机制

在开发过程中总会遇到各种各样的异常,比如最常见的空指针异常、数组越界异常等。这些异常是指在方法不能按照正常方式完成时,可以通过抛出异常的方式退出该方法,在异常中封装了方法执行过程中的错误信息及原因,调用方在获取该异常后可根据业务的情况选择处理该异常或者继续抛出该异常。异常直接影响到程序的健壮性和系统的稳定性,而异常的处理机制的好坏也代表着一门计算机语言的健壮性的好坏,Java作为一门有着优秀的健壮性的语言,自然有着完善的异常机制,而作为开发人员了解全面的异常处理机制以及对异常进行良好的处理至关重要。在J

2020-10-27 10:58:31 416 2

原创 使用Spring Boot 编写一个starter

前面我们介绍了Spring Boot的自动装配原理,对原理了解之后,我们可以编写我们自己Starter包,以便于集成自己的项目,Starter命名主要分为两类,一类为官方命名,一部分为自定义组件命名。为了使得命名更为清晰,一般使用下面的两种约定的方式对Starter组件命名。spring-boot-starter-模块名称,比如spring-boot-starter-web,该方式为官方命名格式 模块名称-spring-boot-starter,比如mybatis-spring-boot-starte

2020-10-15 21:14:35 686

原创 SocketIO、Websocket断开重连问题排查方案

用了SocketIO,Websocket好久了,并且在不同的项目上因为网络的复杂程度以及代理的不同出现了各种websocket断开重连的问题。本篇总结websocket使用过程中的断开重连问题,主要是SocketIO使用过程中的问题。首先是在Nginx代理中遇到的问题,因为websocket是由HTTP协议升级为websocket的,因此我们并不能完全像配置HTTP代理那样配置配置websocket的代理,如下为Nginx提供的官方websocket的配置:location /chat/ {

2020-10-14 17:18:50 5773

原创 Yaml map和list配置的使用详解

YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。它的基本语法规则如下大小写敏感 使用缩进表示层级关系 缩进时不允许使用Tab键,只允许使用空格。 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可 # 表示注释,从这个字符一直到行尾,都会被解析器忽略。YAML 支持的数据结构有三种。本篇将会介绍三种数据结构在Spring Boot中的的使用对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dic

2020-10-14 16:19:41 33403

原创 Spring Boot 访问静态资源 CSS JS 找不到 报404

一般不怎么写前端页面,今天写使用freemarker作为模板文件,使用Spring Boot时,遇到了css、js等静态文件访问不到的问题,查看浏览器控制台发现报404错误,百度了一下,网上很多使用Spring Boot访问静态资源,访问不到,报404的例子,觉得很多例子写的不够详细,这里写一篇博客作为记录,首先需要声明的是不同版本的Spring Boot可能有不同的处理方案,本篇博客的Spring Boot版本为2.0.x的的版本,我们还是从项目说起,所有的静态资源放在classpath:/static/

2020-09-30 21:51:10 2075

原创 一文学习Quartz常用 API 的使用

在任务调度服务Quartz简介与入门一篇我们简单的介绍了Quartz是什么和Quartz的使用,本篇我们介绍Quartz常用的API,这些API将贯穿Quartz的整个使用的过程,首先我们介绍SchedulerFactory的使用。官网这样解释ScheduleFactory,Provides a mechanism for obtaining client-usable handles toSchedulerinstances.在使用调度器(Scheduler)前,调度器需要被实例化。你可以使用Sc..

2020-09-28 21:01:45 1047

原创 Spring解析XML 报 schemaLocation 值 必须具有偶数个 URI。

该错误是在Spring解析自定义标签的时候报的错误,关于Spring解析自定义标签可以参考Spring源码解析之自定义标签的解析与Bean的注册。具体错误如下:org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 45; SchemaLocation: schemaLocation 值 'http://www.springframework.org/schema/beans http: //www.springframework.org.

2020-09-28 18:58:42 2719 1

原创 任务调度服务Quartz简介与入门

Quartz框架是一个全功能、开源的任务调度服务,可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。Quartz调度器包含许多企业级功能,例如对JTA事务和集群的支持。(最简单的调度程序就是简单的定时器,每隔多久执行一次)可以将Quatrz就当成是普通的定时任务。只是经过Quartz封装之后,可以完成更为复杂的任务调度。如果您的应用程序有需要在特定时间执行的任务,或者您的系统有经常性需要维护的工作,那么Quartz可能是您的理想解决方案。Qua

2020-09-27 20:27:06 1150

原创 Spring源码解析之自定义标签的解析与Bean的注册

前面我们降解了Spring中默认标签的解析,下面我们介绍Bean的自定义标签的解析,为何Spring这么强大,就是它具有强大的可扩展性,因此我们的自定义标签也可以通过Spring解析,比如Dubbo的自定义标签,其解析也是委托给BeanDefinitionParserDelegate完成的,调用的方法为:parseCustomElement(Element ele),源码如下所示:public BeanDefinition parseCustomElement(Element ele) { r

2020-09-27 20:26:32 474

原创 Spring源码解析之默认标签的解析与Bean的注册

前面我们介绍了Spring源码解析之容器的创建与XML配置的读取,Spring IOC容器的创建也就是DefaultListableBeanFactory的创建,配置文件的加载最终被解析为Document实例,本篇我们介绍配置标签的解析与Bean的注册,在前面一篇我们最终看到标签的解析与Bean的注册是在XmlBeanDefinitionReader的registerBeanDefinitions(doc, resource)方法中完成的,下面我们查看该方法的源码:public int registe

2020-09-27 20:26:18 156

原创 Spring源码解析之容器的创建与XML配置的读取

在前面我们介绍过Spring将资源抽象为Resource,并且提供了不同的实现处理不同类型的资源,比如File、Http、Ftp、classpath等等,本篇我们讲述Spring容器的创建与资源的加载,对于Spring容器,我们说XmlBeanFactory或者ApplicationContext都可以是Spring容器,都可以从其中获取到Bean,但是其核心类为DefaultListableBeanFactory,创建IOC容器的过程也就是创建DefaultListableBeanFactory实例的过程

2020-09-25 21:29:35 212

原创 Spring 源码解析之资源抽象Resource接口

在Java提供的访问资源的API中,我们可以通过URL指定资源的位置,Java提供的API会使用不同类型的URLHandler去处理,但是它也有不足之处,并不能让所有人获取低层次的资源。比如没有提供从classpath或者ServletContext下访问资源的的标准URL实现。虽然可以为专门的URL前缀注册新的处理程序(类似于http:等前缀的现有处理程序),但这通常是相当复杂的,并且URL接口仍然缺少一些需要的功能,例如检查所指向的资源是否存在的方法。因此Spring提供了对资源访问的抽象,在Sprin

2020-09-24 20:49:01 319

原创 RestTemplate 源码解析与ClientHttpRequestInterceptor拦截器的使用

使用过Spring的对RestTemplate的使用应该非常了解了,它是Spring提供的Http请求客户端工具,本篇博客不再介绍RestTemplate的使用,仅仅对RestTemplate的调用流程进行解析,如果想要了解RestTemplate的使用,可以自行查看Spring的官方文档的Spring MVC部分。首先我们看RestTemplate提供的调用方法,如下RestTemplate提供了很多的API供我们调用,下面仅仅展示一部分:public <T> T getForObjec

2020-09-23 21:54:40 2053

原创 Java 序列化与反序列化原理以及常用序列化技术详解

在平常的工作过程中,我们经常会提到并且用到序列化和反序列化,RPC的使用就是最好的一个例子,那么到底是序列化和反序列化呢,序列化和反序列化有什么用处,Java又是如何实现序列化和反序列化的呢?序列化是将对象的状态信息转换为可存储或者传输的形式的过程,简单的来讲就是将对象转换为字节序列的过程。反序列化就是序列化的逆过程,将字节数组反序列化为对象,恢复为对象的过程。那么序列化和反序列化解决哪些问题呢?将对象序列化为字节数组,使用对象可以通过网络进行进程之间传输并且可以将对象永久存储到存储设备。这就是序列

2020-09-23 19:31:27 553

原创 Spring中的Aware接口的使用——ApplicationContextAware与BeanNameAware

当ApplicationContext创建一个实现org.springframework.context.ApplicationContextAware接口的对象实例时,该实例将会提供一个对ApplicationContext的引用。以下显示了ApplicationContextAware接口的定义:public interface ApplicationContextAware { void setApplicationContext(ApplicationContext applicati

2020-09-22 21:16:53 1266 1

原创 FutureTask的使用与原理解析

在Java 多线程编程简介与线程的创建一篇我们介绍了线程的创建方式,分别为继承Thread、实现Runnable接口和实现Callable接口,本篇我们介绍线程的另一种创建方式FutureTask。相对于Runnable的实现方式不能有返回结果,FutureTask对其进行了适配,使其可以返回一个默认的结果,并且支持Callable方式线程的创建。如下我们先使用一个例子介绍FutureTask的使用:private static void futureTaskRunnable() throws Int

2020-09-22 16:47:31 609

原创 Spring 中时事件处理机制——ApplicationEvent

ApplicationContext中的事件处理通过ApplicationEvent类和ApplicationListener接口提供。如果实现ApplicationListener接口的bean注册到ApplicationContext中,则每次ApplicationEvent发布到ApplicationContext时,都会通知该bean。本质上,这是标准的观察者设计模式。从Spring4.2开始,事件结构得到了显著的改进,提供了一个基于注解的模型以及发布任意事件的能力(也就是说,不一定从Applica

2020-09-21 20:30:37 4572

原创 简析synchronized原理与Java对象中的等待通知机制实现原理

什么是并发编程中的等待通知机制?简而言之就是一个线程修改了一个对象的值,而另一个线程感知到了变化,然后进行相应的操作。在前面的博客Java JUC 并发包组件之LockSupport与Condition的使用中,我们介绍了使用队列同步器实现的等待通知机制,本篇我们介绍使用synchronized实现的Java对象的等待通知机制,等待/通知的相关方法是任意Java对象都具备的,因为这些方法被定义在所有对象的超类 java.lang.Object上,方法和描述如下表所示: 方法名

2020-09-21 19:03:39 422

原创 一文读懂RocketMQ消费者DefaultMQPushConsumer的使用

在一文读懂RocketMQ生产者DefaultMQProducer的使用一篇我们详细介绍了RockerMQ生产者的使用,本篇我们介绍RocketMQ消费者的使用,

2020-09-21 19:03:25 7860 3

原创 一文读懂RocketMQ生产者DefaultMQProducer的使用

前面我们简单的介绍了常用的消息中间件,本篇我们主要介绍消息中间件RocketMQ生产者的使用,RocketMQ实现了两种类型的生产者DefaultMQProducer和TransactionMQProducer,前者生产普通消息,后者生产事务消息。而本篇我们主要介绍DefaultMQProducer的使用。在阅读本篇之前你需要了解RocketMQ的总体结构和RocketMQ的相关概念,这些内容RocketMQ官网已经写的非常清楚,如果不清楚的可以参考。在此之前我们首先介绍Message的使用,Mess

2020-09-18 10:58:03 8738 7

原创 分布式消息中间件概述

目前常用的消息中间件有RabbitMQ、RocketMQ、Kafka等,本篇博客不涉及任何任何消息中间件,只是简单的介绍消息中间件一些概念和解决方案。消息中间件的本质是两个进程之间的通讯,像HTTP、RPC、Webservice都可以进行进程间通讯,那么我们为什么还需要消息中间件这个组件呢?我们考虑一个场景,假如有一个交易系统,交易成功之后需要发送短信通知,如果交易耗时100毫秒,发送短信需要200毫秒,如果使用HTTP则整个交易流程需要300毫秒,而对于短信的实时性并不是那么强,这个时候我们可以将短信

2020-09-16 22:23:13 1867

原创 一文读懂Java线程池ScheduledThreadPoolExecutor的使用与运行机制

ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它主要用来在给定的延迟之后运 行任务,或者定期执行任务。ScheduledThreadPoolExecutor的功能与Timer类似,但 ScheduledThreadPoolExecutor功能更强大、更灵活。Timer对应的是单个后台线程,而 ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。和ThreadPoolExecutor类似,ScheduledTh

2020-09-16 21:27:46 1868

原创 一文读懂Java线程池ThreadPoolExecutor的使用

再实际项目中,我们可能会处理执行时间非常短但是数量非常大的请求,这个时候如果为每一个请求创建一个新的线程,可能会导致性能瓶颈。因为线程的创建和销毁的时间可能会大于任务执行的时间,系统性能就会大幅度降低。JDK1.5提供了线程池的支持,它通过线程的复用技术从而省去线程的频繁创建来达到处理大量并发请求的目的。线程池的原理就是创建了一个运行效率比较优异的“ThreadPool”再池中对线程对象进行创建销毁的管理,使用池时只需要执行具体的任务即可,线程对象的处理再池中被封装了。如下是线程池的一个简单的例子:

2020-09-16 19:44:02 650

原创 Spring Cloud Gateway与Spring Cloud Alibaba Sentinel 网关限流的实现

在前面我们知道Spring Cloud Gateway实现了一个RequestRateLimiter的过滤器,该过滤器会对访问到当前网关的所有请求执行限流过滤器、如果被限流,默认情况下回响应Http-429-Too Many Requests。RequestRateLimiterGatewayFilterFactory默认提供了RedisRateLimiter的限流实现,它采用令牌桶的算法实现限流功能。Spring Cloud Alibaba Sentinel 从1.6版本提供了对Spring C.

2020-09-15 21:08:06 1016

原创 Java Service Provider Interface 之 SPI机制

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。 SPI 的作用就是为这些被扩展的API寻找服务实现。Java中一个经典的SPI实现就是JDBC的Driver的加载机制,在最初我们学习JDBC时,我们需要使用Class.forName("com.mysql.jdbc.Driver")加载数据库驱动。其实在最新版本的JDK中我们可以省略该步骤,该步骤已经在JDK中通过SPI进行了驱动的加载。在DriverMa

2020-09-14 22:30:09 508 1

原创 Docker 镜像常见命令讲解

前面介绍了Docker的安装与部署,并且从镜像仓库拉取运行了一个Hello Word镜像。本篇我们主要介绍与Docker镜像有关的常见命令,镜像仓库和镜像的操作。首先先我们先看一下镜像仓库的常见命令:login、logout、pull、push、search。命令详情如所示:docker logindocker login命令用于登陆到一个Docker镜像仓库,如果没有指定镜像仓库地址,默认为登录的仓库地址为:官方仓库 Docker Hub。如下为docker login 命令的使用与说明:

2020-09-14 21:08:19 358

原创 Java JUC 并发包组件之LockSupport与Condition的使用

本篇我们只介绍LockSupport与Condition的部分API和一些概念,不涉及示例,如果想要示例,可以查看JDK源码的阻塞队列部分,我也写了一篇阻塞队列的文章也可以查看。在Java线程状态与生命周期一篇我们介绍Java的声明周期时介绍过在调用LockSupport的方式时会让线程处于WAITiNG状态和返回RUNNABLE状态。LockSupport定义了一组的公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能,它是构建同步组件的基础工具。LockSupport定义了一组以park开头的方法

2020-09-10 20:43:38 191

原创 java JUC 并发包之阻塞队列——BlockQueue

在学习完java的同步队列、Lock和等待通知机制之后,再来看阻塞队列会觉得阻塞队列更加容易理解。阻塞队列是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入:当队列满时,队列会阻塞插入元素的线程,直到队列不满;阻塞移除:在队列为空时,获取元素的线程会等待队列变为非空。在阻塞队列不可用时,这两个附加操作提供了4种处理方式jdk为我们提供了一下几种阻塞队列,他们的实现方式几乎是相同的,我们后面以一种方式讲述阻塞队列的实现,如下表为jdk为我们提供的几种阻塞队列与描述:阻塞队列 描述

2020-09-10 20:05:42 318

原创 java中原子类与CAS原理

在java.util.concurrent.atomic包中提供了很多原子类,包括三个原子更新基本类型:AtomicBoolean,AtomicInteger,AtomicLong;原子更新数组:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray;原子更新引用类型:AtomicReferenceFieldUpdater,AtomicMarkableReference,AtomicReference;原子更新字段类:AtomicIntegerFie.

2020-09-06 18:39:22 217

原创 Vagrant与Virtual Box 搭建Docker服务与Docker入门

在Vagrant与Virtual Box 搭建centos虚拟机一篇我们使用Vagrant和Virtual Box搭建了一个centos7的虚拟机,今天我们在搭建的虚拟机上搭建docker服务,并且学习docker的一些简单命令,运行docker提供的Hello Word镜像。在安装docker之前,如果已经安装完docker吗,使用下面的命令先卸载docker服务。sudo yum remove docker \ docker-client \

2020-09-06 13:48:11 139

原创 .Linux下MySQL的安装-解压缩安装

1.Linux安装MySQL解压缩版,首先先下载MySQL解压缩版我们可以在官网下载MySQL解压缩版mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz上传到服务器即可2.解压缩下载的MySQL包[root@192 Downloads]# tar -zxvf mysql-5.7.18-linux-glibc2.5-x86_64.tar.gz下面是部分解压缩信息mysql-5.7.18-linux-glibc2.5-x86_64/bin/myisam_ftdump.

2020-09-06 10:15:16 557

原创 Linux下MySQL的安装-rpm包安装

在我们Linux 下MySQL 安装之yum命令安装介绍了使用yum 命令安装MySQL,本篇我们介绍使用rpm包安装MySQL,与使用yum安装一样。rpm安装之前也需要检查是否已经安装过MySQL服务器,具体步骤和用yum安装之前的检查一样。使用RPM安装MySQL我们首先需要下载相应的RPM包,在这之前,我们需要查看自己的系统的内核,然后在镜像网站:http://mirrors.sohu.com/mysql/MySQL-5.7/下载相应的RPM包。我们可以使用uname -a查看系统版本:[

2020-09-06 10:04:48 298

原创 Spring Cloud Alibaba 限流与熔断 — 再谈Sentinel 限流与熔断

前面我们已经介绍了Sentinel的限流的简单使用,今天我们再次讲解Sentinel的限流与熔断的使用,并且介绍几种常见的限流的算法。 所谓限流就是通过限制并发访问数或者限制一个时间窗口内允许的请求数量来保护系统,一旦请求超过限制数量而采取一些处理策略,比如:跳转到错误页面、排队、降级等。限流以损失一部分用户的可用性而为大部分用户提供稳定的服务。下面我们介绍几种常见的限流算法。计数器算法...

2020-09-06 09:46:18 326

原创 Vagrant与Virtual Box 搭建centos虚拟机

搭建虚拟的方式有很多种,比如直接使用virtual workstation+镜像、virtual Box+镜像等等,本篇我们介绍使用virtual box +vagrant搭建虚拟机,再此之前我们需要准备的是VirtualBox-6.0.12-133076-Win、vagrant_2.2.6_x86_64、centos7。对于VirtualBox-6.0.12-133076-Win、vagrant_2.2.6_x86_64的安装比较简单,只需要傻瓜式安装即可,这里不再讲解,直的注意的是这里需要先安装vagr

2020-09-05 17:24:14 292

原创 Spring Cloud Alibaba Dubbo之集群容错、负载均衡、服务降级的使用

其实前面已经介绍过Ribbon负载均衡,在访问量较大的情况下,我们会通过水平扩容的方式增加多个节点来平衡请求的流量,从而提升整体服务的性能。Spring Cloud Alibaba作为一个微服务框架,使用Dubbo作为通讯框架,在Dubbo提供了四种负载均衡策略,分别为随机算法(random)、轮训(roundrobin)、最少活跃调用少(leastactive)、一致性hash算法(consistenthash)。其中随机算法可以针对性能较好的服务器设置权重,请求的概率也会越大,轮训算法是按照公约后的权重

2020-09-04 21:40:27 1030

原创 Spring Cloud 分布式消息—Spring Cloud Stream 自定义通道与分组分区应用

在Spring Cloud 分布式消息—Spring Cloud Stream 简介与入门一篇我们简单了介绍了Spring Cloud Stream,并且使用Spring Cloud Stream提供的默认通道input,output简单的做了一个示例,本篇我们将会使用自定义通道做一个示例,并且介绍Spring Cloud Stream的高级应用,如果对Spring Cloud Stream 不了解可以先去阅读Spring Cloud 分布式消息—Spring Cloud Stream 简介与入门一篇文章.

2020-09-04 17:38:37 1481

原创 队列同步器 AQS原理解析—独占式获取同步状态

在队列同步器 AbstractQueuedSynchronizer 的简单使用一篇我们简单介绍了AbstractQueuedSynchronizer的使用,本篇我们结合上一篇的示例介绍AQS的原理实现。在上一篇我们一直提到的一个词是等待队列,如果获取锁失败,则将当前线程放到等待队列,那么AbstractQueuedSynchronizer中的等待队列到底是什么呢?...

2020-09-03 20:56:43 277

原创 Spring Cloud 分布式消息—Spring Cloud Stream 简介与入门

目前市面上有许多消息代理中间件(下面简称为消息代理),例如 ActiveMQ RabbitMQ、Kafka 、RocketMQ等,在使用这些框架时,我们需要调用它们的API用于发送和接收消息。本篇博客我们使用RabbitMQ作为示例。在单独使用RabbitMq时,我们需要创建RabbitMQ客户端连接,创建Channel,声明一个队列,然后通过Channel发布消息。代码如下所示:

2020-09-03 16:26:58 750

原创 AQS 队列同步器 AbstractQueuedSynchronizer 的简单使用

队列同步器AbstractQueuedSynchronizer,是用来构建锁或者其他同步组 件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获 取线程的排队工作。我们可以看一下前面介绍的重入锁,读写锁、或者信号量、CountDownLatch等源码,你会发现他们的源码中总会有一个静态内部类继承了AbstractQueuedSynchronizer,代码示例如下:abstract static class Sync extends AbstractQueuedSy.

2020-09-01 17:15:56 292

空空如也

空空如也

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

TA关注的人

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