java
文章平均质量分 81
苏雨丶
擅长主流开源框架源码
展开
-
【源码系列】MyBatis与Spring整合原理源码
本文是对之前的MyBatis原理源码一文的补充,工作中都是Mybatis不会单独使用而是整合Spring一起使用,整合以后我们都感觉不到和SqlSession的存在,需要用到哪个Mapper时,直接使用@Autowired注入就行,而且SqlSession默认的实现是线程不安全的,别问我怎么知道的,的类注释告诉我的到这里大家肯定有几个问题想问Spring是如何解决SqlSession的线程安全问题?Mapper接口是怎么注入到Spring容器的?.........原创 2022-08-17 20:20:33 · 1424 阅读 · 2 评论 -
【源码系列】Spring事务执行原理源码
其实事务的源码还是比较好理解的,首先要知道它是基于AOP来实现的,明白事务传播特性,搞清楚各个特性的作用,执行流程主要分为三大步事务准备:通过TransactionManager(事务管理器)、TransactionAttribute(事务注解属性的包装)、TransactionStatus(包含了连接对象、被挂起的事务等)来实例化TransacationInfo对象,事务执行:事务代码执行,成功提交(如果当前事务不是一个全新的事务那么会做空提交,需要第一个创建事务的才提交)、失败回滚(如果当前事务有原创 2022-08-15 15:14:23 · 1656 阅读 · 1 评论 -
RocketMQ 事务消息源码分析 (RocketMQ系列八)
之前已经讲过了普通消息的发送流程,事务消息只是在普通消息的基础上做了一些操作,消息在Producer端发送以后(这里叫半消息),Broker收到消息以后,会判断是否是事务消息,如果是事务消息会替换掉消息的Topic为事务的消息主题,将原本的消息主题和队列信息封装到消息中,等客户端执行完本地事务代码后,告诉Broker半消息是提交还是回滚。提交就是将事务半消息移到目标Topic的队列中,然后客户端就能消费到该消息。回滚的话就是将消息移到系统的另一个操作队列中,标记消息为删除,Consumer永远也消费不到该消原创 2022-07-11 15:43:53 · 632 阅读 · 0 评论 -
记录一下工作中遇到的生产bug以及整个解决过程
今天测试过来问assert服务是不是崩了,所有设计到该服务的接口前端请求都直接超时了,在服务器上通过观察日志发现服务在批量更新站点公式后,才不正常的,一开始以为是更新公式比较耗资源,导致服务器的负载和cpu过高,导致的系统卡死。呆着这样的猜测去验证自己的猜想。于是使用命令来观察服务内存和cpu的占用情况,发现负载和cpu都是正常于是通过命令查看服务的堆栈信息,查看几乎所有线程都处于WAITING状态为了方便观察,于是对其中一个节点进行堆转储,将文件到导到本地的jvisualvm上查看,通过观察线程的原创 2022-06-14 19:49:14 · 329 阅读 · 0 评论 -
Nacos配置中心配置变更,自己编码实现自动刷新的功能
Nacos本身已经支持了@NacosValue的属性刷新功能,必须要在配置文件中打开自动刷新,还必须设置@NacosValue的属性autoRefreshed = true 默认为false,但是我们项目中使用的最多的是@Value来做占位符操作,Nacos并没有支持@Value的属性工作,工作上有个需求,需求内容如下配置中心内容变更,@Value修饰的属性也需要支持刷新值操作。如果有只需要解决问题,不需要知道原理的同学,可以直接把该项目拿过去用,项目中也包含了测试代码,有用的话麻烦Stat一下,该项目我原创 2022-06-09 18:39:55 · 5689 阅读 · 4 评论 -
【源码系列】Nacos服务注册原理源码
Nacos服务注册原理源码客户端服务注册测试单元Nacos自动装配服务注册服务端服务注册集群同步Nacos服务注册原理源码客户端服务注册测试单元我们先看一下Nacos客户端给出的服务注册的测试单元代码测试单元中主要做的事情:构建服务Instance对象通过工厂创建NamingService对象Instance向NamingService(注册中心)注册通过serviceName向注册中心(NamingService)获取实例列表信息测试单元中我们知道客户端根据服务的ip、原创 2022-04-06 20:11:36 · 934 阅读 · 0 评论 -
【源码系列】MyBatis原理源码
Mybatis的核心是Jdk的动态代理和各个组件,整个运行可以分为两大步骤:1. 准备阶段1. 解析配置文件获取全局Configuration对象,该过程中为每个Mapper接口创建MapperProxyFactory对象,2. 有了Configuration对象以后通过构建者模式构建SqlSessionFactory3. 通过SqlSessionFactory创建SqlSession对象,SqlSession包含了Executor(Sql的执行器),如果有插件,Executor会织入插件逻辑(通原创 2022-03-24 17:34:24 · 5556 阅读 · 6 评论 -
Java获得两个日期之间的所有年、月份、日
/** * 获取两个时间段的时间段值 * @param startTime 开始时间 * @param endTime 结束时间 * @param typeEnum 时间类型枚举 * @return */ protected static List<String> getTimePeriodFromTwoTime(Long startTime, Long endTime, TimeTypeEnum typeEnum) { .原创 2022-03-21 19:20:45 · 2959 阅读 · 5 评论 -
RocketMQ pull方式消费消息,无需手动维护offset、集群负载
前言平常我们在使用RocketMQ消息队列消费时,基本使用的都是push模式,有些时候我们也需要通过pull方式来实现我们的功能。我们都知道RocketMQ的push模式底层就是使用的pull模式来实现的,所以我们其实可以自己来实现一些push的功能。别的不说,比较忙。直接上代码。亮点1.实现了push模式的offset、如果不实现这个功能,我们需要自己手动去维护这个offset、我想要一个一劳永逸的办法,不想自己去维护,我们知道push模式就是RocketMQ自己帮我们维护了,我通过源码,调用了pu原创 2021-04-20 19:11:44 · 1556 阅读 · 0 评论 -
Spring中FactoryBean原理解析
FactoryBean创建流程1.判断当前bean是否是FactoryBean,如果是进入FactoryBean的创建流程,不是走普通的Bean创建流程2.给BeanName加上&修饰前缀开始getBean3.在doGetBean时,移除&前缀,去容器缓存中获取,第一次创建基本不没有,没有就将该Bean添加到已经创建的缓存中,要走开始创建流程4.FactoryBean到了创建时(CreateBean)和普通Bean创建流程就一样了5.FactroyBean实例化成功后走getObj原创 2021-03-18 10:52:24 · 671 阅读 · 0 评论 -
RocketMQ Consumer的Push模式启动过程 (RocketMQ系列七)
Consumer启动流程前言上一篇讲了RocketMQ在消息发送的流程,这一篇开始讲Consumer的启动流程,看下Consumer在启动的过程中做了哪些事情。Consumer端消费代码下面是consumer并发消费时的代码,主要分为了Consumer的初始化,以及注册消息并发消费的监听器,最后就是启动consumerDefaultMQPushConsumer consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);consumer.setN原创 2021-01-31 18:55:30 · 859 阅读 · 0 评论 -
RocketMQ消息发送流程 (RocketMQ系列六)
前言上一篇我们讲了Broker的启动流程,我们对Broker在启动阶段做的一些事情有了充分的了解,这一篇我们开始讲Producer的初始化和启动过程以及消息发送过程以及Broker接受到消息请求的处理过程。Producer端发送流程下面是producer发送一条简单消息的代码,我们一句句来分析,看下具体做了哪些事情//初始化发送消息的线程池DefaultMQProducer producer = new DefaultMQProducer("test-group"); //1producer.s原创 2021-01-24 16:57:36 · 708 阅读 · 0 评论 -
Java服务,CPU100%问题如何快速定位?
JVM线上问题排查前言项目运行中,难免会遇到一些问题,有时候cpu占用特别高,有时候内存特别高,出现这样的问题,我们该如何怎么解决,现在我们就从下面示例代码来演示,如何定位到是哪个线程造成的,造成的原因是啥。示例代码public class Deadlock { public static void main(String[] args) throws InterruptedException { Object o = new Object(); new原创 2021-01-18 10:16:28 · 348 阅读 · 1 评论 -
RocketMQ Broker启动流程(RocketMQ系列五)
Broker启动流程前言今天我们讲Broker的启动流程,讲完这篇以后,大家对Broker启动做的事情有一个清晰的认识,这个源码是我自己一点一点啃得,有点硬,后面再整理代码注释的时候,参考了一些博客,我尽可能的说的清楚一些,我表达和总结能力比较弱,有些地方说的可能不清楚,大家可以给我留言,我看到了都会回复的。源码Idea启动Broker找到Broker的启动类,BrokerStartup,然后编辑main方法,修改启动参数,如下图所示环境目录会在下图所示的包中具体配置:ROCKETMQ_原创 2021-01-16 20:42:51 · 1957 阅读 · 0 评论 -
线程创建的五种方法
创建线程的方法继承Thread类public class MyThread extends Thread { @Override public void run() { System.out.println("MyThread"); } public static void main(String[] args) { new MyThread().start(); }}实现Runable接口public cla原创 2021-01-15 13:29:39 · 213 阅读 · 0 评论 -
RocketMQ消费者的负载均衡策略详解(RocketMQ系列四)
RocketMQ消费负载策略Consumer在拉取消息之前需要对TopicMessage进行负载操作,负载操作由一个定时器来完成单位,定时间隔默认20s简单来说就是将Topic下的MessageQueue分配给这些Consumer,至于怎么分,就是通过这些负载策略定义的算法规则来划分。AllocateMessageQueueAveragely平均负载策略,RocketMQ默认使用的就是这种方式,如果某个Consumer集群,订阅了某个Topic,Topic下面的这些MessageQueue会被平均分原创 2021-01-08 18:33:52 · 9259 阅读 · 4 评论 -
RocketMQ整合SpringBoot(RocketMQ系列三)
前言上一篇我们讲了消息的发送和消息消费的一些知识,本篇我们开始讲RocketMQ整合SpringBoot。RocketMQ整合SpringBoot我会讲两种整合SpringBoot的方式,一种使用SpringBoot的starter来整合,另外一种我们自己整合,相对来说,Starter整合方式更加单,不过技多不压身嘛,两种都学习一下。Starter方式整合pom.xml文件<!-- web --><dependency> <groupId>org.spr原创 2021-01-05 14:00:38 · 432 阅读 · 0 评论 -
RocketMQ消息发送和消费相关知识(RocketMQ系列二)
前言上一篇讲了RocketMQ的安装和简单测试了系统自带的测试,本篇将开始讲RocketMQ的api使用、消息发送方式、消费模式,消息的类型。消息//消息Topicprivate String topic;//消息标记 0表示非事务消息private int flag;//一些额外属性,消息tag,key等private Map<String, String> properties;//消息体private byte[] body;//事务消息传递到消息idprivate原创 2021-01-01 20:05:30 · 723 阅读 · 0 评论 -
RocketMQ的安装、角色介绍(RocketMQ系列一)
前言最近一直在学RocketMQ的东西,为了加深对它的印象,决定写一个关于RocketMQ的主题博客,博客会涉及RocketMQ从安装、到使用、集群、以及各种原理源码。笔者水平有限,说的不对的地方,还希望各位老哥能够指出来,毕竟误人子弟不是我的初衷,我也是希望对读者们有一些帮助。简介RocketMQ是一个分布式消息中间件,最初是由阿里团队开发的,经过一系列的迭代升级,经历了淘宝双十一的大流量考验,很多小伙伴可能比较好奇市面上已经有了很多成熟的消息中间件、ActiveMQ、Kafka、RabbitMQ等原创 2020-12-30 16:22:19 · 261 阅读 · 0 评论 -
Java项目本地访问resource目录文件运行正常,打包成jar后提示没有那个文件目录
本地获取方法代码入下://这种方式得到的路径,打包成jar后会访问不到这个路径this.getClass().getClassLoader().getResource(FONT_PATH).getPath()/usr/local/api/fxq-contract-0.0.1.jar!/BOOT-INF/classes!/fonts/SIMSUN.TTF (没有那个文件或目录) //正常的获取方法,只能获取文件流 然后再做操作 InputStream inputStream =this.get原创 2020-08-05 11:17:59 · 1103 阅读 · 0 评论 -
ELK日志分析系统搭建以及springboot日志发送到ELK中
前言安装之前服务器必须装了Java环境,我们这里安装的是7.7.0版本,而且7.7.0版本还必须要求jdk11以上。安装elasticsearch#下载elasticsearch安装包wget https://mirrors.huaweicloud.com/elasticsearch/7.7.0/elasticsearch-7.7.0-linux-x86_64.tar.gz#解压tar -xvf elasticsearch-7.7.0-linux-x86_64.tar.gz 为elastic原创 2020-08-01 16:38:53 · 1088 阅读 · 0 评论 -
i++和 ++i的区别
前言我们平常工作中对某个数进行累加的时候,一般都是用i++,但是我看HashMap和其他一些jdk里面的代码,用到自增基本上用的都是++i,这两个有啥区别呢?我们都知道一个是i++先赋值再自增, 另一个是先自增再赋值。我们只知其然,不知其所以然。今天我尝试给大家解释一下,希望我能表达清楚吧。测试代码首先列出我们的测试代码,你可以想一下这个i会打印几。i++ public static void main(String[] args) { int i = 8;原创 2020-07-02 18:42:48 · 1453 阅读 · 3 评论 -
加强对Aop的理解,自己实现一个简单版的Aop
手写AOP实现思路我们先看下我们平常是如何使用spring的Aop,下面代码是一个比较简单的aop的前置通知的使用。@Component@Aspectpublic class BeforeAspect { @Before("execution(public * com.test.controller..*.*(..))") public void before(JoinPoint joinPoint) { }}首先我们看类注解,@Component、@Aspect原创 2020-06-08 18:59:16 · 490 阅读 · 0 评论 -
spring结合数据库实现策略模式 彻底干掉if
前言我们公司是做电子合同系统的,电子合同里面最重要的就是CA证书,其中颁发机构有浙江CA,湖北CA、天威诚信 、 沃通CA、CFCA 不同的行业客户对证书的要求都不一样,普通的客户一般用天威诚信或者湖北CA就好,有一些金融客户,可能会要求必须使用某个CA机构的比如必须要求沃通,为了满足这个需求,想到了设计模式中的策略模式,不同的客户在调用的时候使用不同的策略就行了。策略模式策略模式是将多个类似的业务公共的部分抽离出来成一个接口类,然后具体的业务由各自的策略类去实现这个接口,在使用的时候由一个上下文原创 2020-06-04 15:31:25 · 478 阅读 · 0 评论 -
Java对象深拷贝和浅拷贝
前言拷贝功能,在电脑上我们经常用到,也许换个名字更容易理解,那就是复制功能。我们平常复制以后就是两个独立的文件,修改其中一个文件的内容并不会影响另一个文件的内容。我们平常在写代码的时候,也经常会有这样的场景,把一个对象完完全全的复制一份出来,那么我们Java里面的对象拷贝是啥样的呢?拷贝方式浅拷贝我们先不说什么事浅拷贝,我们先举个栗子????1: 同类型对象直接将值赋给另一个对象 Son son = new Son() .setName("小明");原创 2020-06-03 15:04:32 · 290 阅读 · 0 评论 -
Pdf文件定位关键词坐标
Pdf定位关键词坐标之前就做过关键词获取坐标的demo,但是有时候会发现有些关键字,文档上面明明存在的,但是通过demo中的代码来获取,就是获取不大,后面查资料,发现大家都有这个情况,后面在一篇博客中看到个比较好的解决方案,因为itext 5.x 获取文本的代码textRenderInfo.getText();这个只能获取到单个字符的坐标,比如,甲方,如果你去匹配甲这个关键词,是能定位到坐标的,但是如果你同时去获取甲方这个关键词就会获取不到,后面在这个博客上面看到既然能获取到单个字,于是我有了下面原创 2020-06-01 16:26:42 · 4245 阅读 · 1 评论 -
springboot文件上传到本地并返回可预览的文件路径
上传接口建一个springboot的web项目,然后写一个上传并返回文件路径的接口,接口代码如下: /** * 本地保存路径 */ @Value("${file.path}") private String dirPath; @RequestMapping(value = "upload") public String upload(MultipartFile file) throws IOException { InputStre原创 2020-05-23 15:24:30 · 4825 阅读 · 2 评论 -
Mybatis使用ResultMap中嵌套collection标签主键id不封装的问题
mapper.xml文件如下<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.f...原创 2020-05-08 10:58:06 · 1557 阅读 · 0 评论 -
Redis在docker启动的数据持久化
Redis在docker启动的数据持久化最重要的就是在command的后面加一行代码开启 aof日志备份--appendonly yes,因为docker中redis数据存储就是在/data目录下面,所以只要将这个目录挂载到宿主机的某个路径下就可以啦,下次重启redis会先读取这个aof文件version: "3"services: redis: image: 'redis:4...原创 2020-03-17 15:37:39 · 1528 阅读 · 1 评论 -
Zookeeper实现的分布式锁
Zookeeper实现的分布式锁zookeeper是一个分布式协调中间件,既可以用来做分布式的id还可以用来做配置中心、还有我们接下来要说的分布式锁。在说分布式锁之前要先介绍一下zookeeper,它是树形结构,每个节点都可以存储值和创建子节点。而zookeeper的节点一共分为四种分别是临时节点,持久化节点,临时有序节点,持久化有序节点。Zookeeper节点类型临时节点顾名思义,...原创 2020-03-02 19:16:13 · 156 阅读 · 0 评论 -
基于Redis 自定义注解和Aop防止form表单重复提交
防止form表单重复提交解决方案1、 前端form表单加载的时候,去请求后端的生成formId的接口2、 后端在生成formId接口将formId存储到缓存中,再返回给前端3、 前端在form表单提交的时候在请求头中携带一个formId的参数,值为加载时获取到的formId4、 后端基于AOP拦截请求,判断请求头是否携带formId,并判断是否存在缓存中如果不在,告诉前端fromId不...原创 2020-02-13 10:51:31 · 409 阅读 · 2 评论 -
SpringBoot RabbitMq 消息投递手动签收 Only one ConfirmCallback is supported by each RabbitTemplate
异常信息出现在工作实际开发中,用到了队列信息,为了消息的可靠性投递,我使用到了手动签收的方式,开始只有一个地方使用到了,客户调用接口,有一个地方需要用到异步回调,由于中间件的异步特效,我就用队列来做,开始这一块一点问题没有,客户还在正常使用,后面由于一个其他的需求,也需要使用到了队列,后面也加上了这种手动签收的方式来做,在本地测试的时候也没啥问题,由于以前的代码没改 所以就没测那一块的功能...原创 2020-01-15 11:27:43 · 7905 阅读 · 2 评论 -
程序包sun.security.tools.keytool不存在问题解决
Jdk 1.8使用import sun.security.tools.keytool.CertAndKeyGen;来生成证书,导致项目打包时报下面这个异常,程序包sun.security.tools.keytool不存在问题[ERROR] /Users/fxq/Public/WorkSpace/webank-demo/src/main/java/cn/isuyu/webank/demo/Cert...原创 2020-01-04 14:43:49 · 6960 阅读 · 0 评论 -
ffmpeg 视频压缩问题 it.sauronsoftware.jave.EncoderException: Metadata:
最近在做一个H5视频认证的功能,对接了百度的活体分析接口,客户需要接入到app当中,开始遇到个各种各样的问题安卓webview嵌入我们的h5页面,调用摄像头的时候,打开的却是文件管理器,后期发现该问题是客户自己的权限没设置好,后期就能打开摄像头啦IOS对接正常,当客户使用安卓手机调用的时候,就一直停留在验证页面不动对于一直停留在验证页面不动的问题,客户对接时,我通过内网穿透,让他们连接我...原创 2019-12-27 16:02:02 · 7082 阅读 · 0 评论 -
Java类加载机制 双亲委托模式
加载阶段类加载阶段是由类加载器负责根据一个类的全名类读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区内,然后将其转换为一个与目标类型对应的java.lang.Class对象实例,这个Class对象在日后就会作为方法区中的该类的各种数据的访问入口。JVM支持两种类型的类加载器,分别为引导类加载器(BootStrap ClassLoader) 和自定义类加载器(User-Def...原创 2019-12-02 14:18:16 · 299 阅读 · 0 评论 -
java File base64流 byte[] 的相互转换
工作中经常用到文件与base64 等其他状态的互相转换,每次都记不住,只好把各种文件的转换方法写个博客记录下来,方便下次使用的时候,直接复制就好。File转Base64//文件路径转换base64Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get("../data/1.jpg")))Base64转File...原创 2019-11-21 15:49:00 · 2172 阅读 · 0 评论 -
springboot集成RabbitMq异常 Channel shutdown: channel error; protocol method
异常信息2019-11-13 14:07:18.431 INFO 10702 --- [ 127.0.0.1:5672] c.f.o.a.l.rabbitmq.publisher.TestSender : 信息投递成功,messageId:39f52873-37ca-49b1-9054-b71bf7cf26c8----收到消息,开始消费-----d订单id:39f52873-37ca-4...原创 2019-11-13 15:10:39 · 20632 阅读 · 10 评论 -
平常面试中出现比较频繁关于HashMap面试题以及答案
HashMap工作原理HashMap基于hashing原理,我们通过put()和get()方法存储和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode方法来计算hashcode,然后找到了bucket位置来存储值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链...原创 2019-10-23 16:48:01 · 1422 阅读 · 0 评论 -
mybatits动态多数据源配置mysql 数据库读写分离
数据库读写分离数据库读写分离环境搭建:https://github.com/niezhiliang/mysql-master-slave-docker数据库读写分离一般分为两种,一种是静态的,一种是动态的,顾名思义静态是配置了不会变,有局限性,而动态的会根据业务的需求自动切换数据源静态这种方式一般适用于项目需要依赖两个不同的数据库,而不是所谓的读写分离的主从数据库。比如一个数据库没有用户表...原创 2019-08-12 19:23:47 · 303 阅读 · 0 评论 -
Springboot2.x配置ssl证书同时支持http和https两种协议
1.准备一份xxx.jks的证书一份,放置resources目录下2.在application.yml配置证书的一些参数,以及项目的http端口和https接口 配置如下:server: port: 8080 custom: httpPort: 9090 ssl: key-store: classpath:ssl.jks key-password: 1234...原创 2019-09-02 16:46:00 · 1597 阅读 · 0 评论