目录

chen 的个人博客

VX:TiAmo151028
Phone:13403656751
Email:zxydczzs@gmail.com

SpringBoot ContextLoaderListener、Servlet 有更新!

一、问题 SpringBoot v2.3.2 中使用 ContextLoaderListener.getCurrentWebApplicationContext() 获取 WebApplicationContext 为空 二、原因 要使用这个 API 我们首先得明确它是个什么玩意儿,ContextLoaderListener 实际上就是一个监听器,作用就是启动 Web 容器时,自动装配 ApplicationContext 的配置信息,它实现了 ServletContextListener(三大生命周期监听之一); 摘个图 Spring 实现了 Tomcat 提供的 ServletContextListener 接口,写了一个监听器来监听项目启动,一旦项目启动,会触发 ContextLoaderListener 中的特定方法 contextInitialized 也就是说 Tomcat 的 ServletContext 创建时,会调用 ContextLoaderListener 的 contextInitialized(),这个方法内部的 initWebApplicationCon....

Git Revert Revert!

一、前言 最近在工作中遇到个很有趣,让人费解的一个操作,举例子说明。 有两个分支,一个分支 A,一个分支 B,他们两个要合并在一起后,跟分支 C 合并,一通操作下来合并好之后,在 commit 记录中也可以看到两个分支的提交,然后提测,被告知分支 A 的功能没有实现,当时很费解,最后排查下来,发现在提测分支 C 中,没有分支 A 的代码,且无论你怎么 merge 分支 A,永远都是无任何修改。 当时有点不明所以,接着排查,发现在提测分支 C 中,有个操作为 Revery 分支 A 的提交记录,会不会和这个有关呢?将这个现象告知公司大佬后,由于时间比较紧张且分支 A 的代码没有多少,就手动将分支 A 的代码 copy 到了提测分支 C 中让测试人员继续。 之后在公司大佬研究后给出了个答案,大概问题出现原因为,提测分支 C 中的 Git 提交线只要存在针对于某次 merge 的 revert 操作,就会一直忽略掉这个 merge 里包含的提交内容。 如果对这句话不太了解的话,咱们用通俗的话来讲就是,你撤回了这个分支上的某次提交,Git 就会认为你不需要这一段代码,所以你想要把代码在合并上....

Junit4 单元测试注入bean失败

一、报错截图 二、单元测试截图 三、解决 @SpringBootTest(classes = XxxApplication.class) 改为 @SpringBootTest(classes = XxxApplication.class, webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)

分布式任务调度平台XXL-JOB

一、下载源码 GitHub 地址:https://github.com/xuxueli/xxl-job/releases gitee 地址:http://gitee.com/xuxueli0323/xxl-job/releases 文档地址:https://www.xuxueli.com/xxl-job/ 二、初始化“调度数据库” 三、运行 xxl-job-admin 先修改 properties 文件中的数据库密码,改成自己的。 运行 四、打开管理后台 网址输入 http://localhost:8080/xxl-job-admin/ 五、创建执行器 六、创建任务 七、项目中使用 pom.xml 添加依赖 1 <!-- https://mvnrepository.com/artifact/com.xuxueli/xxl-job-core --> 2 <dependency> 3 <groupId>com.xuxueli</groupId> 4 <artifactId>xxl-job-core</ar....

Centos7 Nacos安装 有更新!

环境 CentOS7 64bit JDK8+; Maven 3.2.x+; 下载 zip 包 https://github.com/alibaba/nacos/releases 两种解压方式,看个人喜好。本文使用 unzip 下载的 zip 包。 上传至服务器,解压 1unzip nacos-server-2.0.3.zip 进入 nacos/bin 目录 1cd nacos/bin 执行 startup.sh 1sh startup.sh -m standalone 查看启动日志 1cd 2cd nacos/bin/logs 3cat start.out 启动成功 网址输入 服务器 IP:8848/nacos 例如:127.0.0.1:8848/nacos 默认用户名密码都是 nacos 登录成功

Spring Retry && Guava Retry 有更新!

Spring Retry 一、引入 Maven 依赖 1 <!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry --> 2 <dependency> 3 <groupId>org.springframework.retry</groupId> 4 <artifactId>spring-retry</artifactId> 5 <version>1.3.1</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> 8 <dependency> 9 <groupId>org.aspectj</groupId> 10 <artifactId>aspectjweaver&l....

发票开具 有更新!

该文章已经加密。

Navicat连接数据库报错 Host XXX is not allowed to connect to this MySQL server

因为 MySQL 配置了不支持远程连接引起的 解决 1、在服务器中登录 MySQL root 用户 1mysql -u root -p 2、依次执行命令 1use mysql; 2 3select host from user where user='root'; 3、将 host 设置为通配符 Host 列指定了允许用户登录所使用的 IP,比如 user=root Host=192.168.1.1。这里的意思就是说 root 用户只能通过 192.168.1.1 的客户端去访问。 user=root Host=localhost,表示只能通过本机客户端去访问。而 % 是个通配符,如果 Host=192.168.1.%,那么就表示只要是 IP 地址前缀为“192.168.1.”的客户端都可以连接。如果 Host=%,表示所有 IP 都有连接权限。 1update user set host = '%' where user = 'root'; 4、修改完成后执行 flush privileges 使配置立即生效 1flush privileges; 5、再次使用 nav....

日常开发bug记录

场景 查询数据库中时间区间内的数据 由于一些细节操作,我需要在后端将时间截取,只要年月日。 这里用到了 hutool 的 DateUtil 工具中的 parse 和 format 方法解析。 1 String endDate = "2022-02-14 59:59:59"; 2 String format = DateUtil.format(DateUtil.parse(endDate), "yyyy-MM-dd"); 3 System.out.println(format); 最后结果 原因 请求参数因为是 59:59:59,正确应为 23:59:59 这里是 59,所以工具会给加两天的时间,14 就变成了 16 一定要擦亮眼睛!

Windows 启动RocketMQ

一、下载 RocketMQ https://rocketmq.apache.org/docs/quick-start/ 下载完成后将其解压至文件夹中,如“E:\rocketmq\rocketmq-4.9.2” 二、设置环境变量 NAMESRV_ADDR = 127.0.0.1:9876 ROCKETMQ_HOME = E:\rocketmq\rocketmq-4.9.2 三、启动 mqnamesrv.cmd 路径:E:\rocketmq\rocketmq-4.9.2\bin 使用命令行执行以下命令 1start mqnamesrv.cmd 四、启动 broker 路径:E:\rocketmq\rocketmq-4.9.2\bin 使用命令行执行以下命令 1mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true 五、启动接收者 路径:E:\rocketmq\rocketmq-4.9.2\bin 使用命令行执行以下命令 1start tools.cmd org.apache.rocketmq.example.quic....

Centos7 安装openjdk

一、下载安装 1yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel 二、设置环境变量 1vim /etc/profile 1export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-1.el7_9.x86_64 2export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 3export PATH=$PATH:$JAVA_HOME/bin 4 三、验证 1java -version

Spring AOP实践

概念详解 Pointcut:切点,决定处理如权限校验、日志记录等在何处切入业务代码中(即织入切面)。切点分为 execution 方式和 annotation 方式。前者可以用路径表达式指定哪些类织入切面,后者可以指定被哪些注解修饰的代码织入切面。 Advice:处理,包括处理时机和处理内容。处理内容就是要做什么事,比如校验权限和记录日志。处理时机就是在什么时机执行处理内容,分为前置处理(即业务代码执行前)、后置处理(业务代码执行后)等。 Aspect:切面,即 Pointcut 和 Advice。 Joint point:连接点,是程序执行的一个点。例如,一个方法的执行或者一个异常的处理。在 Spring AOP 中,一个连接点总是代表一个方法执行。 Weaving:织入,就是通过动态代理,在目标对象方法中执行处理内容的过程。 实例 1package com.zxy.demo.aspect; 2 3import com.alibaba.fastjson.JSON; 4import org.aspectj.lang.JoinPoint; 5import org.aspec....

Java邮箱发送服务

一、邮箱开启 SMTP 服务 这里使用 QQ 邮箱为示例,其他邮箱大同小异 登录 QQ 邮箱; (https://mail.qq.com/) 登录成功后点击“设置”; 导航栏选择“账户”,下滑找到“POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务”开启“SMTP”服务; 点击开启按钮,经过短信验证后开启服务; 短信发送后,点击我已发送,验证成功后会有一个弹出框,有一个“授权码”需要将其记下来。 二、测试邮件发送 pom 依赖 1 <!-- hutool --> 2 <dependency> 3 <groupId>cn.hutool</groupId> 4 <artifactId>hutool-all</artifactId> 5 <version>5.7.10</version> 6 </dependency> 7 8 <!-- javax.mail --> 9 <depende....

Stomp协议 关键点(持续更新) 有更新!

监听 如果需要添加监听,我们的监听类需要实现 ChannelInterceptor 接口,在 springframework 包 5.0.7 之前这一步我们一般是实现 ChannelInterceptorAdapter 抽象类,不过这个类已经废弃了,文档也推荐直接实现接口。 https://www.jianshu.com/p/4762494d42f1 https://www.jianshu.com/p/9103c9c7e128 https://spring.io/guides/gs/messaging-stomp-websocket/ 1package org.springframework.messaging.support; 2 3import org.springframework.messaging.Message; 4import org.springframework.messaging.MessageChannel; 5 6public interface ChannelInterceptor { 7 // 在消息发送之前调用,方法中可以对消息进行修改,如果....

SpringBoot @Autowired注入失败的一些情况和避开的方式 有更新!

问题 一个类在初始化到 Bean 容器时,需要将另一个类也初始化,而另一个类初始化的时候依赖的其他的 Bean,如果按照正常的顺序则会抛出异常,注入失败等。 解决 修改 Bean 加载顺序,先将依赖的 Bean 加载完成后在执行后两步即可。 需根据 SpringBoot 特性 如果使用了@Autowired 注解注入,会优先加载依赖的 Bean。 或者使用@order、@DeependsOn 等,可以自己网上查找详细资料,按照本身业务去选择。

swagger-ui页面接口的入参出参与代码实体类不一致有差异

Swagger 发现 Swagger 请求示例的参数和代码层面的请求实体不一致。 一、清除浏览器缓存,如果不能解决问题,看第二条。 二、这个接口请求实体的@ApiModel 命名有相同命名。 1@ApiModel("查询详细信息入参") 2public class PerionInfo implements Serializable{ 3 private static final long seriUID = -1L; 4 @ApiModelProperty("姓名") 5 private String name; 6 @ApiModelProperty("性别") 7 private String sex; 8 @ApiModelProperty("生日") 9 private String birday; 10} 11 1@ApiModel("查询详细信息入参") 2public class CarInfo implements Serializable{ 3 private static final long seriUID = -1L; 4 @ApiMode....

RPC框架实现原理

一、什么是 RPC 框架 RPC,全称为 Remote Procedure Call,即远程过程调用,是一种计算机通信协议。 比如现在有两台机器:A 机器和 B 机器,并且分别部署了应用 A 和应用 B。假设此时位于 A 机器上的 A 应用想要调用位于 B 机器上的 B 应用提供的函数或是方法,由于 A 应用和 B 应用不在一个内存空间里面,所以不能直接调用,此时就需要通过网络来表达调用的方式和传输调用的数据,也即所谓的远程调用。 二、RCP 框架的实现原理 1、建立通信 首先要解决通讯的问题:即 A 机器想要调用 B 机器,首先得建立起通信连接。主要是通过在客户端和服务器之间建立 TCP 连接,远程过程调用的所有相关的数据都在这个连接里面进行传输交换。 通常这个连接可以是按需连接(需要调用的时候就先建立连接,调用结束后就立马断掉),也可以是长连接(客户端和服务器建立起连接之后保持长期持有,不管此时有无数据包的发送,可以配合心跳检测机制定期检测建立的连接是否存活有效),多个远程过程调用共享同一个连接。 2、服务寻址 解决寻址的问题:即 A 机器上的应用 A 要调用 B 机器上的应用 B....

Spring AOP的实现原理以及应用场景。

AOP 应用场景 记录日志; 监控方法运行时间(监控性能); 权限控制; 缓存优化(第一次调用查询数据库,将查询结果放入内存对象,第二次调用则直接从内存对象返回,不需要查询数据库); 事务管理(调用方法前开启事务,调用方法后提交关闭事务); AOP 实现原理 Spring 中 AOP 的两种实现方式: JDK 动态代理; Cglib 动态代理; JDK 动态代理 引入依赖,有 Spring、单元测试和日志管理; 1<dependencies> 2 <!-- Spring --> 3 <dependency> 4 <groupId>org.springframework</groupId> 5 <artifactId>spring-context</artifactId> 6 </dependency> 7 8 <!-- 单元测试 --> 9 <dependency> 10 <groupId>junit</groupId&....

Java设计模式 有更新!

设计模式简介 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如果大厦的一块块砖石一样。项目中合理的运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。------摘自菜鸟教程 设计模式的类型 根据设计模式的参考书 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式-可复用的面向对象软件元素)中所提到的,总共有 23 种设计模....

Java 多态

首先来看什么是多态 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作。 多态性是对象多种表现形式的体现。 多态的优点 消除类型之间的耦合关系; 可替换性; 可扩充性; 接口性; 灵活性; 简化性; 多态存在的三个必要条件 继承; 重写; 父类引用指向子类对象:Parent p = new Child(); 1package com.zxy.demo.Test; 2 3public class DuoTai { 4 public static void main(String[] args) { 5 Shape s1 = new Circle(); 6 Shape s2 = new Square(); 7 Shape s3 = new Triangle(); 8 9 s1.draw(); 10 s2.draw(); 11 s3.draw(); 12 } 13} 14 15class Shape{ 16 void draw(){} 17} 18 19class Circle extends Shape{ 20....