- 博客(91)
- 资源 (1)
- 收藏
- 关注
原创 从ReentrantLock到AQS源码阅读
ReentrantLock是使用AQS实现的一种可重入的独占锁,并且提供了公平和非公平两种策略。ReentractLock的内部类Sync继承了AbstractQueuedSynchronizer抽象类,并且提供了两个内部类FairSync和NonfairSync(即公平锁与非公平锁的落地实现),而具体采用哪一种加锁策略则则是由ReentractLock的构造函数进行指定。public ReentrantLock() { sync = new NonfairSync();}public R
2022-01-13 13:59:29
554
原创 ThreadLocal源码阅读笔记
功能描述ThreadLocal解决了访问共享变量的阻塞问题,并且不需要像CAS操作一样牺牲CPU资源,它为每一个线程维护了一个变量副本,每个线程在访问ThrealLocal里面的变量时实际上访问的是自己线程内的变量副本,并且这个线程内的变量副本与其他线程的变量副本相互隔离,互不影响。也就是说,ThreadLocal包裹的变量是线程级变量。源码解刨ThreadLocal通过一个内部类ThreadLocalMap进行数据的保存,并将自己本身作为key,从get方法入手。public T get() {
2022-01-13 13:59:12
396
原创 LongAdder源码阅读笔记
一、功能描述LongAdder通过创建多个副本对象,解决了多线程使用CAS更新同一个对象造成的CPU阻塞,加快了对线程处理的速度。当多个线程同一时刻更新一个AtomicLong类型的变量时,只有一个线程能够更新成功,其他线程则更新失败,继续尝试更新。当使用LongAdder类型的变量时,由于副本数组的存在,线程不一定直接更新变量的本身而是更新副本数组,这样多线程请求的对象变多了,从而减少了更新时间,当需要使用变量值时,返回的值是基础变量的值加上数组内每一个副本的值的和。二、源码解读LongAdd
2022-01-13 13:57:58
273
原创 SpringBoot自动配置分析
SpringBoot程序中的启动类,需要编写在项目根包中,而编写在子包中的类就可以实现自动装配处理。这种功能是如何实现的?Spring容器又是怎样启动的?还是需从启动类开始分析。
2021-12-11 11:49:30
569
1
原创 详解SpringBoot自动装配原理
文章目录一、从RedisAutoConfiguration源码分析自动装配二、@EnableConfigurationProperties注解三、@Import注解3.1 类导入3.2 ImportSelector导入3.3 ImportBeanDefinitionRegistrar导入四、application.yml配置提示五、自定义Starter组件一、从RedisAutoConfiguration源码分析自动装配SpringBoot主张一种零配置的开发方式,特别是第三方框架的整合往往只需要在项.
2021-12-07 17:59:45
2373
3
原创 聊一聊SpringBoot中的异步编程
从WEB服务器的响应模式来看,Web服务器为用户的每一次请求都分配了一个处理线程,可以称之为用户线程,也就是说本次请求的所有内容都交由这个线程来处理。如果用户单次请求提交的并行任务较多且业务复杂,单一线程的处理速度就会变慢。为了提升服务器的响应速度,可以采取异步的模式,在用户线程中新开一个或多个任务线程,让程序并行的处理用户请求,最后将处理结果交由用户线程整合后返回。一、启用异步线程1.1 Callable接口实现异步处理Callable接口可以开启新线程执行,并将执行的结果返回主线程,那么可以
2021-12-04 15:38:09
1300
1
原创 SpringBoot整合WebSocket
一、WebSocket与Http的区别HTTP是应用层上的一个单向的、无状态的、基于请求与响应的协议。http协议本身是没有持久通信能力的,当客户端向服务器发送HTTP请求时,接收到请求后,服务器会将响应发送给客户端。每个请求都与一个对应的响应相关联,在发送响应后客户端与服务器的连接会被关闭。这种的基于请求响应的通讯方式有一点不足,服务器端无法主动向客户端推送数据。Websocket是应用层上的一个全双工的有状态协议。websocket以ws://或wss://开头,它必须依赖 HTTP 协议进行一次
2021-12-01 20:18:28
5275
10
原创 SpringBoot整合WebService
WebService是一种传统的SOA技术架构,它不依赖于任何的编程语言,也不依赖于任何的技术平台,可以直接基于HTTP协议实现网络应用间的数据交互。面向服务架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。WebService主要用于异构平台之间的整合与调用,例如请求者
2021-11-28 17:03:09
6090
3
原创 SpringBoot使用ShedLock调度任务
前言在分布式的场景下,SpringBoot程序以集群的方式部署,这些程序中运行着相同的代码,如果其中有定时任务的话,所有的程序都会运行该任务,这样就会导致任务的重复执行。由于所有的定时任务在集群的不同节点值中,所以需要一个专属的数据存储空间(通常使用Nosql数据库)来记录每一个定时任务的名称以及当前执行任务的主机与任务执行时间,而后在集群中不同的节点执行任务前会查看数据存储中是否存在指定任务的执行记录,如果没有记录则可以启动该节点任务,如果已经有此任务的相关信息,则代表任务已经执行,则跳过该节点任务
2021-11-27 11:58:35
877
1
原创 SpringBoot定时任务
SpringBoot中使用SpringTask处理定时任务,这是一种相较于传统的quartZ组件更加简单的形式,在方法上使用@Scheduled注解可以设置定时任务,任务分为3种类型。No.类型解释1fixedDelay每次任务执行完之后的xx时间后继续执行,单位为ms2fixedRate固定时间循环执行,单位为ms3cron当时间达到设置的时间会触发任务其中cron任务需要编写cron表达式,也可以选择在网站快速生成(快速生成cron表达式)。新建一
2021-11-27 08:48:18
649
原创 Prometheus搭建SpringBoot监控环境
SpringBoot程序通过Actuator接口访问,每次只能拿到当前状态的数据,如果想要统计分析监控数据,那么应该拿到每一个时刻的监控数据,存储到数据库中,并进行可视化展示。在微服务场景下,针对于SpringBoot程序的监控,Spring全家桶提供有SpringBootAdmin组件。如果不考虑微服务的情况,可以使用NodeExporter监控SpringBoot程序所运行的主机信息(Cpu、内存等),使用Actuator监控SpringBoot程序的运行信息。使用Prometheus采集监控数据存储
2021-11-23 22:12:08
1440
1
原创 SpringBoot四大神器之Actuator
使用Actuator可以在SpringBoot程序运行时通过http请求的方式动态的监控和管理程序,官方对其功能的介绍如下:Spring Boot includes a number of additional features to help you monitor and manage your application when you push it to production. You can choose to manage and monitor your application by us
2021-11-23 22:09:50
13885
4
原创 Thymeleaf模板引擎
在经典的java单体项目中(前后端不分离),页面的编写往往采用JSP技术(Java Server Page),JSP的最大特点是可以在页面中编写java代码,实际上jsp经过转化生成Servlet,再编译生成*.class文件存储在WEB容器中,而对用户请求的处理正是由Servlet完成的。使用JSP开发的主要问题是页面过于混乱,在HTML中编写JAVA代码往往只能由后台工程师完成,极大的提升了开发的难度,而页面的调试也需要先转换为Servlet再打包才能看到执行结果。SpringBoot项目默认使用内
2021-11-19 11:26:44
1071
1
原创 SpringBoot使用JSR303进行数据验证
SpringBoot支持JSR303的验证规范。JSR303 规范(Bean Validation 规范)为 JavaBean 验证定义了相应的元数据模型和 API。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode , 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constra
2021-11-14 11:20:00
1962
原创 SpringBoot全局处理
一、全局错误页SpringBoot默认已经存在了错误页的显示处理,例如访问一个不存在的路径:如果考虑到前后端分离的设计,那么应该使用JSON进行数据交互,返回页面的形式就不能满足要求。新建返回数据包装类,规定任何交互数据都以此为规范:public class ResultMessage<T> { private Integer code; // 返回编码 private String message; // 信息 private T result; // 返回结果
2021-11-14 11:18:49
1150
原创 SpringBoot配置Https访问
Https协议HTTP(Hypertext transfer protocal)是一种详细规定了浏览器和万维网服务器之间相互通信的规则,通过因特网传送万维网文档的数据传送协议。HTTPS(Hypertext transfer protocal over Secure Socket Layer)是以安全为目标的http通道,https的安全基础是ssl,因此加密的详细内容就需要ssl。https协议需要到ca申请证书(一般免费的证书很少)。http是超文本传输协议,信息是明文传输的,https则是具有
2021-11-10 21:58:42
17285
2
原创 SpringBoot整合Web过滤器、监听器、拦截器
整合过滤器SpringBoot定义一个web过滤器只需要其继承HttpFilter类,并在类上使用@WebFilter注解声明过滤路径。@Slf4j@WebFilter("/*") // 过滤器路径public class MessageFilter extends HttpFilter { public void doFilter(HttpServletRequest request, HttpServletResponse response,
2021-11-08 21:27:27
1498
原创 SpringBoot文件上传
服务器处理上传文件一般都是先在请求中读取文件信息,然后改变名称保存在服务器的临时路径下,最后保存到服务器磁盘中。本次以thymeleaf搭建demo,因此需要引入thymeleaf依赖库。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <ver
2021-11-07 11:59:31
364
原创 SpringBoot读取资源文件
在Java项目中,资源文件一般都为 *.properties 文件(只能存储key-value格式的数据),SpringMVC中提供有MessageSource接口进行资源文件的读取,在SpringBoot中也支持同样的操作。读取资源文件在resources目录下新建i18n文件夹,在文件夹中新建message.properties文件:title=SpringBoot开发框架desc=官方网址: https://spring.io/projects/spring-boot修改applicati
2021-10-31 19:22:59
2196
原创 SpringBoot获取Web内置对象
Web内置对象主要有request、response、session、servletContext,而实际上session、servletContext都可以通过request对象来进行获取。一、通过注入方法参数获取内置对象@RestController@RequestMapping("/innerObject")public class InnerObjectAction { @RequestMapping("/get") public Map<String, Object
2021-10-31 13:22:53
288
原创 SpringBoot属性注入
一、@Value注解注入属性SpringBoot默认可以将application.properties文件或application.yml文件中定义的属性值注入到java类中,这种注入实际上是通过java类属性的setter方法进行的。例:将application.yml中的以下属性注入到类中:## 自定义属性petshop: name: 睿芽宠物 introduce: 种类齐全,安全可靠 licences: 1、上市许可证,2、疫苗许可证 infos: "{'phone':'36x
2021-10-27 17:44:46
2106
4
原创 SpringBoot返回多种格式的数据
一、SpringBoot整合FastJson1、引入FastJson依赖包maven项目:<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.78</version></dependency>gradle项目:compile 'com.alibab
2021-10-27 14:56:12
2035
原创 Lombok使用详解(测试修改标题)
lombok可以通过注解的方式在编译期动态的为类添加方法。一、配置IDEA中使用lombok1、导入lombok依赖包。<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId>
2021-10-24 12:56:35
1456
3
原创 Gradle构建SpringBoot项目
一、新建一个microboot的gradle项目,并在项目根目录新建gradle.properties文件project_group=com.itproject.version=1.0.0project_jdk=11二、在项目根目录新建dependencies.gradle文件,负责管理依赖的版本。// 定义所有要使用到的版本号ext.versions = [ springboot : '2.5.5', log4jtoslf4j
2021-10-21 17:56:47
3799
原创 Gradle学习笔记
gradle同maven、ant一样,可以作为构建工具进行项目的构建,不同的是,gradle中的包可以被项目所引用(也就是说相比较于构建工具,gradle更像是一个框架)。生命周期gradle生命周期包括初始化阶段、配置阶段、执行阶段。初始化阶段解析整个工程中所有的Project,构建所有的Project对应的project对象。配置阶段解析所有project对象中的task,构建好所有task的拓扑图。执行阶段执行具体的task及其依赖task。#mermaid-svg-ANXlJx1hf
2021-10-20 17:30:39
781
原创 Groovy学习笔记
基础语法groovy是一种用于java虚拟机的一种动态语言,与java语言一样,被编译为.class文件后在jvm上执行。不同的是,groovy既可以以类的方式执行,也可以以脚本的方式执行。与大多数动态语言类似,groovy可以省略结束符;。// 类的形式 class HelloGroovy { static void main(args) { println('hello groovy !!!') }}//直接写脚本println('hello groovy
2021-10-13 14:58:30
1138
2
原创 Log4J的使用
Log4j的简单使用新建maven项目,引入依赖库<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version></dependency>在src/main/resources文件夹中新建log4j.properties文件(properties文件一定要在r
2020-09-06 17:31:51
174
原创 MyBits-mapper动态代理方式(接口方式)的CRUD
原则:约定优于配置。硬编码方式:*.javaConfiguration conf = new Configuration();conf.setName("myProject");配置方式:*.xml<name>myProject</name>约定方式:默认值name为myProject实现步骤约定的目标:省略掉statement,即根据约定可以直接定位出SQL语句。新建一个接口,用于操作MyBits,接口中的方法必须遵循以下约定:方法名和mapper.
2020-08-12 21:17:27
181
原创 MyBits--Statement方式的增删改查
根据ID查询新建一张Student数据表DROP TABLE IF EXISTS student;create table student( sid INT AUTO_INCREMENT, name VARCHAR(50), age INT, graname VARCHAR(50), CONSTRAINT pk_sid PRIMARY KEY(sid));INSERT INTO student(
2020-08-11 22:36:29
200
原创 MyBits开发入门
MyBits可以简化JDBC的操作,实现数据的持久化。MyBits中文官网使用Maven配置:入门–>安装–>Maven依赖MyBits Jar包下载下载好mybits的jar包后,新建java工程,并引入该jar包(mybits-3.5.5.jar),随后新建一张数据表: drop table person; create table person( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(2
2020-08-10 20:37:23
487
原创 Java中常见的时间日期类
Date类在整个JAVA程序的设计过程之中,日期时间是一个非常重要的话题,同时几乎所有的项目开发都不可能离开日期时间的处理操作,而整个Java里面对于日期时间也提供有一系列的工具类供开发者使用。java.util.Date 类是Java之中获得日期时间的最简单的程序类,这个类可以通过直接实例化Date类对象的形式获取当前的日期时间。范例:获取当前的日期时间import java.util....
2020-08-07 13:04:27
663
原创 ES6新增功能
变量Javascript使用var定义变量存在以下问题:可以重复声明变量:var a=2;var a=5;alert(a);无法限制修改(js里面没有常量的定义)没有块级作用域(var定义的变量都是全局变量)ES6新增了let和const定义内容。let和const定义的内容都不允许重复定义,其中let定义变量,const定义常量。函数ES6中可以使用箭头函数:()=>{}如果只有一个参数,()可以省略。如果只有一个return值,{}可以省略。let show = (
2020-08-07 12:36:49
404
原创 Maven基础操作
Maven介绍Maven是基于项目对象模型(POM),可以通过一小段信息来管理项目的构建、报告和文档的软件项目管路工具。Maven环境搭建访问Maven官网,点击列表左侧的Download。点击下载:apache-maven-3.6.3-bin.zip将下载好的apache-maven-3.6.3-bin.zip解压到当前目录,打开目录。在计算机上右键属性,选择高级系统设置,环境变量。选择系统变量,点击新建,在弹出的新建系统变量中填写maven目录信息,点击确定。选中path点击编辑,在
2020-07-09 10:50:40
259
原创 JVM优化
JVM小工具jps:打印Hotspot VM进程(VMID、JVM、参数、main()函数参数、主类名/Jar路径)【打印线程】:输入:jps -l2.jstat:查看Hotspot VM运行时信息(类加载、内存、GC[可分代查看]、JIT编译),命令格式:jstat -gc 12260 250 20【查看Tomcat垃圾回收统计】:输入:jstat -gc 12260 250 20【参数含义】参数描述S0C、S1CSurvivor区创建时大小S0U、S1U
2020-06-27 15:44:36
202
原创 JVM垃圾回收
JVM总体结构类加载子系统和方法区:类加载子系统负责从文件系统或网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间。除了类信息外,方法区中可能还会存放运行时常量池信息,包括字符串常量和数字常量(这部分常量信息是class文件中常量池部分的内存映射)。Java堆:java堆在虚拟机启动时建立,它是Java程序最主要的内存工作区域,几乎所有的Java对象实例都存放在Java堆中。堆空间是所有线程共享的,这是一块与Java应用密切相关的内存空间。直接内存:Java的NIO库允许Java
2020-06-27 11:09:02
227
原创 基础排序算法
冒泡排序原理:从第一个数开始,依次往后比较,如果前面的数比后面的数大就交换,否则不作处理。这就类似烧开水时,壶底的水泡往上冒的过程。选择排序插入排序
2020-06-23 18:27:11
178
原创 哈希表查找
前面查找方法的共同特点:通过关键字值与给定值进行比较,来确定位置。效率取决于比较次数。理想的方法是:不需要比较,根据给定值能直接定位记录的存储位置。这样需要在记录的存储位置与该记录的关键字之间建立一种确定的对应关系,使每个记录的关键字与一个存储位置相对应。哈希表的特点和结构hashtable也叫做散列表,有多种结构,其中最常见的是采用顺序表+链表,主结构采用顺序表,每个顺序表的节点单独引出一个链表。哈希表是如何添加数据的计算哈希码(调用hashCode()函数,结果是一个int型的值,整数的哈希码
2020-06-23 10:23:06
1224
原创 查找树
二叉查找/搜索/排序树BST(binary search/sort tree)二叉排序树可以是空树或具有以下性质的树:若它的左子树不为空,则左子树上的所有结点均小于它的根结点若它的右子树不为空,则右子树上的所有结点均大于它的根结点它的左、右子树也分别为二叉排序树。注意:对二叉排序树进行遍历,得到有序集合。平衡二叉树(Self-balancing binary search tree)自平衡二叉树,又称为AVL树(有别于AVL算法),它可以为一棵空树否则需满足以下性质:它的左、右两个子树
2020-06-22 19:01:55
480
原创 线性表查找
线性表的查找可以采用顺序查找和二分查找来完成,在进行查找操作时,与数据存储结构关系不大,即不论采用的是顺序表还是链表,查找的基本思路都是一致的。顺序查找逐个比较查询,如果找到,返回数据或索引,如果最后也没找到,返回null或-1,在各个节点查找概率相同的情况下,默认查询长度为一半长度,所以时间复杂度:T(n) = O(n)【在成绩中查询分数为100的第一个分数】package com.search;/** * 在分数数组中查询指定分数的索引 * 时间复杂度:T(n)=O(n) * 空间复杂
2020-06-22 19:01:39
932
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人