目录

chen 的个人博客

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

标签: Java (44)

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....

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

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

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 // 在消息发送之前调用,方法中可以对消息进行修改,如果....

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 多态

首先来看什么是多态 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口,使用不同的实例而执行不同操作。 多态性是对象多种表现形式的体现。 多态的优点 消除类型之间的耦合关系; 可替换性; 可扩充性; 接口性; 灵活性; 简化性; 多态存在的三个必要条件 继承; 重写; 父类引用指向子类对象: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....

Java设计模式 有更新!

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

悲观锁、乐观锁、自旋锁、读写锁、共享锁、排它锁、统一锁、分段锁。 有更新!

悲观锁 1、定义 具有强烈的独占和排它特性,它指的是对数据被外界(包括本系统当前的其他食物,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。 2、Java 悲观锁实现之 synchronized synchronized 就是典型的悲观锁,相当于不管哪一个线程(例如线程 A),运行到这个方法时,都要检查有没有其他线程 B 或者 C、D 等正在用这个方法(或者该类的其他同步方法),有的话要等正在使用 synchronized 方法的线程 B 或者 C、D 运行完这个方法后再运行此线程 A,没有的话,锁定调用者,然后直接运行。 补充 1/** 2 * @author ZhangXiaoYu 3 * @date 2021/5/13 9:25 4 */ 5public class Thumbnail { 6 Object obj = new Object(); 7 //synchronized修饰普通方法,锁对象是this对象。 8 public synchronized void test(){ 9 10 } 11 12 //sy....

MacOS启动SpringBoot项目时报错【Logging system failed to initialize using configuration from 'logback.xml '】 有更新!

由于是第一次操作 MacOS 系统,在将 Java 环境变量配置好,IDEA 等一系列都安装好后,把项目代码拉了下来,然后运行,结果报错 1Logging system failed to initialize using configuration from 'logback.xml ' 反复找解决方案,最终定位到了 logback.xml 中创建日志文件目录的问题,因为原先在 windows 环境下,logback.xml 中的日志文件存放在/home/xxx 目录下,切换到了 MacOS 系统后由于 home 是不允许创建任何东西的,所以需要以下步骤。 1、进入根目录; 2、编辑 auto_master 文件 1sunshiqiang@sunshiqiangdeMac-mini / % cd / 2sunshiqiang@sunshiqiangdeMac-mini / % sudo vim /etc/auto_master 3、将 home 一行注释掉。 1# 2# Automounter master map 3# 4+auto_master # Use directory....

简单学习数据结构 有更新!

数据结构简介 数据结构是为实现对计算机数据有效使用的各种数据组织形式,服务于各类计算机操作。不同的数据结构具有各自对应的适用场景,旨在降低各种算法计算的时间与空间复杂度,达到最佳的任务执行效率。 常见的数据结构可分为[线性数据结构]和[非线性数据结构],线性数据结构:[数组]、[链表]、[栈]、[队列];非线性数据结构:[树]、[图]、[散列表]、[堆]。 数组 数组是将相同类型的元素存储与连续内存空间的数据结构,其长度不可变。 1// 初始化一个长度为5的数组arr 2int[] arr = new int[5]; 3// 元素赋值 4arr[0] = 1; 5arr[1] = 2; 6arr[2] = 3; 7arr[3] = 4; 8arr[4] = 5; 或者可以使用直接赋值的初始化方法 1int[] arr = {1,2,3,4,5}; 可变数组 [可变数组]是经常使用的数据结构,其基于数组和扩容机制实现,相比普通数组更加灵活。常用操作有:访问元素、添加元素、删除元素。 1// 初始化可变数组 2List<Integer> arr = new ArrayLis....

Stack && LinkedList 有更新!

栈是一种具有[先入后出]特点的抽象数据结构,可以使用数组或链表实现。 1Stack<Integer> stack = new Stack<>(); 我们知道 Java 是不推荐使用 Vector 以及它的子类 Stack 的,因为有更好的替代品,比如:ArrayList、LinkedList,CopyOnWriteArrayList......,当然它也有它的有点,就是它是线程安全的,但也得结合使用场景,比如在单线程无竞争的场景它就是额外的开销了,但是在多线程的环境下也有更好的替代它实现线程安全的方法,所以这里不建议使用。 栈的特性:先入后出也可以使用 LinkedList 来实现,具体实现方法: Stack 1/** 2 * @author ZhangXiaoYu 3 * @date 2021/9/6 11:50 4 */ 5public class TestStack { 6 public static void main(String[] args) { 7 //栈,先入后出,最先入栈的最后出栈。 8 Stack<Integer&g....

volatile关键字与内存可见性 有更新!

1package com.zxy.demo.thread; 2 3import lombok.Data; 4 5/** 6 * @author ZhangXiaoYu 7 * @date 2021/9/2 9:26 8 */ 9public class ThreadDemo1 { 10 //volatile关键字与内存可见性 11 /* 12 * new一个线程子类实例并start,线程内部睡眠200毫秒后将flag设置为true 13 * 主线程使用while循环,如果线程子类的成员变量flag为true时,输出一句话后break出循环。 14 * 问题1:在主线程while循环时,flag已经为true,却没有跳出循环,为什么? 15 * 这是内存可见性的问题。当多个线程操作共享数据时,彼此不可见。 16 * 基本可以理解为,ThreadDemo线程先从主存中把数据读取过来,读取到的是false,然后修改为true,就在还未来得及把true同步到主存 17 * 时,main进来了,这是main读取到的还是false,所以形成死循环,就在main循环时,ThreadD....

int和Integer的区别以及自动装箱\拆箱机制 有更新!

Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。 Java 为每个原始类型提供了包装类型: 原始类型: boolean,char,byte,short,int,long,float,double 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double 测试用例: 1/** 2 * @author ZhangXiaoYu 3 * @date 2021/8/31 14:29 4 */ 5public class AutoUnboxingTest { 6 public static void main(String[] args) { 7 Integer a = new Integer(3); 8 Integer b = 3; 9 int....

Tomcat启动时Creation of SecureRandom instance for session ID 缓慢

一、查找 java.security 文件所在位置 [root@ecs-s6-xlarge-2-linux-20191210145334 shanhe]# find / -name java.security /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el6_10.x86_64-debug/jre/lib/security/java.security /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el6_10.x86_64/jre/lib/security/java.security 二、打开 java.security 文件 [root@ecs-s6-xlarge-2-linux-20191210145334 shanhe]# vi /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el6_10.x86_64/jre/lib/security/java.security 三、修改“securerandom.source=file:....

取消dom4j生成的xml的xml头 有更新!

原先是这样 String requestXml = document.asXML(); System.out.println(requestXml); <?xml version="1.0" encoding="UTF-8"?>//dom4j生成的头部信息,明显我不需要。 <xml xmlns="http://www.w3.org/1999/xhtml"><block><value><block><field>asd</field><value><block><field>asd</field></block></value><value><block><field>asd</field></block></value></block></value><statement><block><value>&....

dom4j设置XML命名空间 有更新!

附代码: Java: Document document= DocumentHelper.createDocument(); Element root = document.addElement("xml", "http://www.w3.org/1999/xhtml"); String requestXml = document.asXML(); System.out.println(requestXml); pom.xml <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j --> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.1</version> </dependency> 输出: <xml xmlns="http://www.w3.org/1999/xhtml">&....

Java判断文件是否为图片类型且MultipartFile转File

private MimetypesFileTypeMap mtftp; mtftp = new MimetypesFileTypeMap(); mtftp.addMimeTypes("image png tif jpg jpeg bmp"); String contentType; try { contentType = mtftp.getContentType(multipartFileToFile(multipartFile)); } catch (IOException e) { e.printStackTrace(); } String type = contentType.split("/")[0]; if(!"image".equals(type)){ //非图片类型 } /** * MultipartFile 转 File * * @param file * @throws Exception */ public File multipartFileToFile(MultipartFile file) throws IOException { File toFile = ....