![](https://img-blog.csdnimg.cn/20200419095156674.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
Java
文章平均质量分 54
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Deniro Lee
这个作者很懒,什么都没留下…
展开
-
说说 JSON 格式的弊端与解决方法
JSON 格式是目前最流行的数据交互格式,广泛应用于前后端分离的系统。但也有一些场合不适合使用 JSON 格式。原创 2022-09-03 09:04:40 · 1028 阅读 · 1 评论 -
说说如何在 Java 中实例化某个类的内部类
前提是这个内部类必须是 public 。假设外部类需要实例化某个类的内部类。那么必须首先实例化内部类的所在类,然后再通过 .new 语法来实例化这个内部类。下面是一个示例:public class DotNew { public class Inner { } public static void main(String[] args) { DotNew dn = new DotNew(); DotNew.Inner dni = dn.new I原创 2022-04-05 18:17:59 · 1691 阅读 · 0 评论 -
说说 Java 的静态内部类
Java 的静态内部类就是定义在一个类的内部,并且标注为 static 的类。由于类是静态的,所以不需要通过外围类的实例来创建。下面是一个示例:public class Outer { private static final Logger log = LoggerFactory.getLogger(Outer.class); private static class Inner { public int value() { return 1;原创 2022-04-05 18:15:34 · 2107 阅读 · 0 评论 -
说说 Java 内部类的基本用法
先从一个示例说起。该示例实现了迭代器模式的数组,可添加、可遍历数组内部的元素。而且还可以判断是否已到了数组末尾。首先定义了一个接口,本质上是一个迭代器://迭代器接口public interface Selector { //判断是否到了数组末尾 boolean end(); //获取当前索引所在元素 Object current(); //进入下一元素 void next();}接下来是主类:// 数组序列public原创 2022-03-20 18:25:35 · 532 阅读 · 0 评论 -
比较 Java 静态工厂方法与构造函数
1 什么是静态工厂方法Java 静态工厂方法是在方法前加上 public static,让这个方法变为公开、静态的方法。该方法返回该类的一个实例,就好像一个工厂生产出一个产品。所以称之为静态工厂方法。在 Boolean.java 中有一个静态工厂方法示例:public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }这里返回了一个 Boolean 实例。2 比较静态工厂方法与构造函数2.1 名原创 2022-03-13 17:50:38 · 986 阅读 · 0 评论 -
说说如何安装 Openfire
Openfire 是一个基于 XMPP 协议的 IM 服务框架。这里我们来说一说如何安装它。1 下载 zip 安装包首先下载 Openfire 安装包,下载路径为:http://www.igniterealtime.org/projects/openfire/这里以 zip 安装包为例,数据库采用 postgresql。2 web 方式安装解压后,进入 bin 目录,运行 openfire.bat :浏览器打开该地址: http://windows10.microdone.cn:9090/se原创 2022-03-13 17:46:22 · 2567 阅读 · 0 评论 -
RocketMQ 事务消息示例分析
1 示例模式RocketMQ 事务消息示例包含一个生产者、消费者、NameServer 以及 Broker 服务,它们之间的关系如下:RocketMQ架构上主要分为四部分[^1]:Producer:消息发布的角色,支持分布式集群方式部署。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。Consumer:消息消费的角色,支持分布式集群方式部署。支持以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的原创 2022-03-06 10:48:32 · 4659 阅读 · 0 评论 -
Seata XA 模式示例分析
文章目录1 下载示例2 示例结构3 业务服务 business-xa3.1 模块结构3.2 Controller 层3.3 Service 层3.4 stock Feign 客户端3.5 order Feign 客户端4 库存服务 stock-xa4.1 服务层 StockService4.2 数据源配置5 订单服务 order-xa5.1 服务层 OrderService5.2 account feign 客户端6 账户服务 account-xa6.1 服务层 AccountService7 测试7.原创 2022-03-06 10:40:52 · 1719 阅读 · 0 评论 -
使用 Spring JdbcTemplate 框架出现 oracle 数据源连接泄露问题的解决方法
1 问题应用运行一段时间之后,无法执行写入数据库操作。底层使用的是 druid 连接池。2 原因使用 Spring JdbcTemplate 框架执行 oracle sql 语句之后,发现逻辑连接没有释放:而同一套代码执行 PostgreSQL 语句之后,Spring JdbcTemplate 框架会主动释放逻辑连接:由于逻辑连接没有被释放,导致之后的线程在排队等待逻辑连接,从而导致线程阻塞。3 解决在执行语句后,主动回收连接:try { DataSource d原创 2021-12-11 09:23:47 · 947 阅读 · 0 评论 -
Java jar 命令行运行程序如何引用第三方依赖包
1 引言mybatis generator 是一个命令行运行工具,可以生成 mybatis 代码。但它需要依赖数据库驱动 jar,否则会抛出 ClassNotFoundException 异常。Exception in thread "main" java.lang.RuntimeException: Exception getting JDBC Driver at org.mybatis.generator.internal.JDBCConnectionFactory.getDrive原创 2021-12-05 20:17:56 · 2376 阅读 · 0 评论 -
分布式事务框架 Seata 与 Hmily 横向比较
从支持的模式种类、团队规模来看,Seata 框架更占优势。原创 2021-12-04 19:13:10 · 1628 阅读 · 0 评论 -
说说在 Java 中如何比较两个对象
Common Lang 中的 Builder 包内提供了一个 DiffBuilder 类,可以比较两个对象,并返回不同的部分。首先在要比较对象的类中实现 Diffable 接口,然后实现 DiffResult diff(T obj) 方法。在DiffResult diff(T obj) 方法中,新建一个 DiffBuilder 对象,把需要比较的类属性一一放入 DiffBuilder 中。DiffBuilder 的构造函数有三个入参,lhs 是当前对象,rhs 是要比较的对象,style 是比原创 2021-11-22 22:03:57 · 1266 阅读 · 0 评论 -
Arrays$ArrayList 的 Object 对象转换为 List<Object> 对象的技巧
在一个开发案例中,需要把一个 Object 对象转换为 List<Object> 对象。这个 Object 对象本质上是 Arrays$ArrayList,也就是 Arrays 类内部的 ArrayList 类。$ 是类与它的内部类之间的表示分隔符。Java 中可以通过 xxx.getClass().getName() 的方式得到一个对象所对应的类全名。如果这个内部类是 public,那么我们可以通过点分法来进行显式转换,形如: (Arrays.ArrayList) xxx。可惜的是这个 A原创 2021-08-20 21:30:15 · 1291 阅读 · 0 评论 -
比较各种初始化 List 方法的便捷性
1 常规方式常规的 List 初始化方法是先创建一个 ArrayList 对象,然后再把需要初始化的数据一个个添加进列表中,就像这样: List<String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c");2 匿名内部类方式匿名内部类方式是使用 {{}} 双括号语法, 外层的 {} 先定义了一个匿名内部类,然后在内层的 {} 进行数据初始化: List<String原创 2021-08-20 21:25:26 · 249 阅读 · 0 评论 -
说说如何在 logback 中打印debug日志,并可定义屏蔽某些包的debug日志
首先是在项目的 resources 文件夹内新建一个名为 logback-spring.xml 文件。然后在 root 节点设置日志级别为 debug,形如:<root level="DEBUG"> <appender-ref ref="console"/> <appender-ref ref="timeFileOutput"/> </root>运行结果:这样会输出项目中所有依赖包的 debug 日志。我们可以利用 l原创 2021-06-19 22:03:05 · 7204 阅读 · 0 评论 -
说说在 logback 中如何输出与主日志不同的独立业务日志文件
首先定义好 appender,然后定义一个 logger 节点,引用刚才定义的appender。logger 节点有以下三个属性,具体说明如下。完整示例如下:<appender name="interceptorTimeFileOutput" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日志名,指定最新的文件名,其他文件名使用FileNamePattern --> <File>${原创 2021-06-19 21:59:30 · 356 阅读 · 0 评论 -
说说在 logback中如何配置日志的控制台输出与文件输出
通常情况下,日志是由一个抽象层 + 实现层的组合来搭建[i]。spring-boot-starter 其中包含了 spring-boot-starter-logging ,该依赖内容就是 Spring Boot 默认的日志框架 logback,所以实际开发中我们不需要直接添加该依赖[ii]。因为我们需要对日志进行更多控制,所以需要增加 logback配置。在项目的 resources 文件夹内新建一个名为 logback-spring.xml 文件。logback-spring.xml 只有在Spr原创 2021-06-19 21:53:19 · 2036 阅读 · 0 评论 -
说说如何使用 Spring jdbc 来执行存储过程
Spring jdbc 提供了jdbcTemplate 对象,该对象定义了 execute 方法可用于执行存储过程。该方法存在许多重载方式,我们使用的是execute(CallableStatementCreator csc, CallableStatementCallback action)。CallableStatementCreator 对象用于定义调用存储过程的入参与出参。CallableStatementCallback 对象用于定义执行以及接受存储过程的返回值。这两个对象都采用lambda表达原创 2021-05-30 08:56:38 · 709 阅读 · 0 评论 -
说说如何把一个POJO形式的Bean对象转换为 Map形式
一个POJO形式的Bean对象,包含一系列的属性定义以及属性所对应的 get 与 set 方法。因此我们需要使用Java的反射方法 getDeclaredFields()来获取这个对象中的字段列表。因为属性一般被定义为private,所以必须使用getDeclaredFields()方法,这个方法可以得到某个类的所有声明字段,即包括public、private和proteced,但是不包括父类的申明字段1。以下是实现代码:private Map<String, Object> toMap(Ob原创 2021-05-30 08:52:51 · 806 阅读 · 0 评论 -
There is no PasswordEncoder mapped for the id “null“ 问题的解决方法
(1) 问题描述使用 postman 执行 POST请求获取访问令牌 URI(/oauth/token)时,响应返回:{ "error": "unauthorized", "error_description": "Full authentication is required to access this resource"}查看后台日志发现抛出There is no PasswordEncoder mapped for the id “null” at org.springfram原创 2021-05-01 08:33:06 · 4611 阅读 · 4 评论 -
说说把 List 传入不定长入参的方法
因为不定长入参本质上是 String[],即字符串数组,所以可以通过toArray(new String[]{})进行转换。形如:list.toArray(new String[]{})。比如Spring Security的 ClientDetailsServiceBuilder#authorizedGrantTypes() 就是一个带有不定长入参的方法:实际转换方法为:...原创 2021-05-01 08:26:20 · 3354 阅读 · 2 评论 -
巧用Java List.removeAll()方法判定列表中元素是否都是某集合中的元素
假设我们有这样一个需求,需要判定配置的 OAuth2 授权类型,是否都在有效范围内。OAuth2 的授权类型只能是这五种:“refresh_token”,“password”, “client_credentials”, “authorization_code”, “implicit”,因为用户可以配置的值可能不在这五种授权类型中,所以需要判定。removeAll(Collection<?>c)方法用于从列表中移除指定 collection 中包含的所有元素,我们可以利用这个方法来进行判定。原创 2021-05-01 08:22:33 · 631 阅读 · 1 评论 -
MyBatis自定义拦截器与 pagehelper组件冲突导致自定义拦截器不生效的解决方法
1 问题描述利用 MyBatis 的 @Intercepts 注解自定义了一个拦截器,在纯净环境中运行正常。放入一套Spring框架中不生效。2 原因分析利用 IDEA 的 Jar 包图谱分析器发现存在2个不同版本的 mybatis-spring-boot-starter:怀疑是与 com.github.pagehelper组件不兼容,因为它内部也是利用 MyBatis 的拦截器实现语句自动分页功能的。利用Maven 的exclusions 标签进行冲突检验:<dependency>原创 2021-03-13 16:54:24 · 3428 阅读 · 1 评论 -
说说发现 Jar 包存在冲突的方法
1 基本用法点击需要排查 Jar 冲突的项目,然后点击右上的 “Show Dependencies”按钮,生成 Jar 依赖图谱:如果依赖的包很多,就会太小,看不清。这时可以右键点击Jar包依赖图谱,选择 Actual Size,会以实际尺寸打开依赖图谱。还可以在图谱中键入 CTRL + F,打开搜索框,输入我们要查看的 jar 包关键字:如果存在冲突,图谱就会以红线进行标注。比如这里的 mybatis 存在两个版本(3.5.6 与 3.4.6):2 实战发现一个项目使用 MyBati原创 2021-03-13 16:48:28 · 578 阅读 · 0 评论 -
Spring 框架的 CommandLineRunner 以组件形式发布后无法执行问题的解决方法
1 问题描述写了一个组件,内部使用 @Component 与 @ConfigurationProperties 注解来读取 yml 格式的配置文件。因为需要一些初始化操作,所以实现了 CommandLineRunner 接口,并在 run() 方法来进行初始化工作。@Component@ConfigurationProperties(prefix = "xxx")public class DatasourceMapperConfig implements CommandLineRunner {…原创 2021-03-07 10:27:35 · 1903 阅读 · 0 评论 -
自主开发的、带有 @Component 的组件在Spring Boot 项目中不生效的解决方法
(1)问题描述开发了一套组件,以 jar 形式发布。然后在 Spring Boot 项目中使用 pom引用后,无法调用到在组件中用 @Component 注释的类。(2)原因分析默认情况下,@ComponentScan注解会扫描当前包及其所有子包中的组件。而 @SpringBootApplication 注解包含了@ComponentScan,所以 Spring Boot 框架会自动扫描 Spring Boot启动类当前包及其所有子包中的组件类。而我们的组件因为不在自动扫描范围内,所以无效。(3)问原创 2021-03-07 10:25:04 · 3853 阅读 · 4 评论 -
说说迭代器设计模式
迭代器设计模式一般用于迭代遍历集合中的元素。假设我们有一个书架,上面放着很多书。我们希望把这个书架中所有书的名字打印出来。这时就会用到迭代器设计模式。我们先利用 UML 把类关系图绘制出来:要理解这一张图,我们需要首先了解以下概念。分解后再理解就会很容易。1 基础概念(1)类组成一个类分为三大部分:类名、属性列表与操作列表。每一个属性或者操作具体格式为:[可见性权限] [属性或方法名]:[返回类型] [中文说明]。这里的 [中文说明] 在 UML 中并没有,这里为了方便理解,所以加上了中文原创 2021-02-21 12:45:40 · 262 阅读 · 2 评论 -
NoSuchMethodException: org.apache.ibatis.javassist.bytecode.analysis.Executor.query问题的解决方法
(1)问题描述自定义了一个 MyBatis 拦截器,用于拦截查询语句。拦截器的签名为:@Component@Intercepts( @Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} ))public class SelectSqlInterceptor原创 2021-02-21 11:01:48 · 820 阅读 · 0 评论 -
源码分析 dynamic-datasource-spring-boot-starter 组件负载均衡策略
dynamic-datasource-spring-boot-starter 组件自带了两个负载均衡算法1:LoadBalanceDynamicDataSourceStrategy 轮询。RandomDynamicDataSourceStrategy 随机。其中轮询是默认算法。这两个算法类都实现了 DynamicDataSourceStrategy 接口:所以如果需要自定义负载均衡算法,就可以实现DynamicDataSourceStrategy 接口。该接口只定义了一个determ原创 2021-01-30 11:02:20 · 1139 阅读 · 6 评论 -
IntelliJ IDEA 快捷键说明大全(中英对照、带图示详解)
因为觉得网络上的 idea 快捷键不够详尽,所以特别编写了此篇文章,方便大家使用 idea O(∩_∩)O~其中的英文说明来自于 idea 的官网资料,中文说明主要来自于自己的领会和理解,英文说明只是作为参考。重要的快捷键会附带图示,进行详细的说明。每一部分会先列出所有的快捷键说明表,如果有不清楚的地方,再看后续的图示详解。1 编辑【Editing】 快捷键 英文说明原创 2017-06-07 18:04:54 · 69937 阅读 · 44 评论 -
说说 Google Guava 集合
Guava 工程是被 Google 的 Java 项目广泛依赖的核心库。谷歌从日常的工作中提取出了很多高效率的 API 方法,从而诞生了 guava 工具包。guava 的优点是:高效设计良好的 API ;遵循高效的 java 语法实践;代码更简洁,节省时间与资源,提高开发生产力。guava 的意思是番石榴。Guava 包提供了很多特性,这次我们主要讲讲集合。1 初始化利用 Guava 的静态工厂方法,可以更简洁地初始化集合中的元素。JDK 方式:Guava 方式:2原创 2020-08-30 17:11:48 · 354 阅读 · 0 评论 -
说说 Java Map 映射
Java Map 是一种键值对的映射集合,在实际编程过程中,很常见。具体有以下这些实现类:HashMap 用到了哈希函数。哈希函数是一种映射关系,根据数据的关键词 key ,通过一定的函数关系,计算出该元素存储位置的函数。address = H [key]一种实际的数据结构是拉链式的链表结构:1 HashTable 与 HashMapHashTable 的作者是: Arthurvan Hoff、Josh Bloch、Neal Gafter。 而 HashMap 的作者是: Arthur原创 2020-08-29 16:24:27 · 1113 阅读 · 0 评论 -
说说 Java Set 集合
Java Set 集合用于存放不同的元素。JDK 中存在以下几种 Set 集合实现方式:红黑树是一种自平衡二叉搜索树,它的每个节点都被 “ 着色 ” 为红色或者黑色,这些节点的颜色被用来检测树的平衡性。红黑树广泛应用 Linux 的进程管理 、 内存管理,设备驱动及虚拟内存跟踪等一系列场景中。JDK 中还存在一种 NavigableSet 类。表示 Java Collection Framework 中的可导航集 。NavigableSet 接口继承自 SortedSet 接口。TreeS原创 2020-08-29 16:23:14 · 165 阅读 · 0 评论 -
说说 Java 队列
队列是一个 “ 先进先出 ” ( FIFO )集合。即从集合的一端放入元素,再从另一端去得到它们,元素放入集合的顺序和被取出的顺序是相同的。队列在并发编程中尤为重要,因为它们可以安全地将对象从一个任务传送到另一个任务。1 基本用法LinkedList 实现了 Queue 接口,并且实现了一些方法用于支持队列行为。2 优先级队列优先级队列可以按照元素的优先级来决定下一个需要弹出的元素。比如一个消息传递系统,某些消息比其他消息更重要,应该尽快处理,这时可以将其设置为最高优先级,让其优先处理。原创 2020-08-29 16:22:13 · 177 阅读 · 0 评论 -
说说 Java 堆栈
堆栈是“后进先出”(LIFO)集合。因为最后压入栈的元素,会被第一个 弹出栈。就好像堆叠在一起的盘子,必须把上面的盘子取出,才能取出下面的盘子。强行取出底下的盘子就会造成结构不稳,引起坍塌。1 基本用法Java 使用了一个新的类 ArrayDeque 来实现堆栈结构:输出:2 Stack 类为何不推荐使用 Java Stack 类?因为 Stack 类继承了 Vector 类,也就继承了 Vector 中所有公有方法。而 Vector 作为动态数组,它提供了在数组中任何位置添加或者删除原创 2020-08-29 16:21:08 · 952 阅读 · 0 评论 -
说说 Java List 列表
Java List 列表定义了一系列的操作方法,这里总结如下:LinkedList 除了继承了 List 的操作方法之外,还定义一些特殊的方法:其中有些是同义词,也就是说,这些方法的执行效果是相同的。1 ArrayList 与 LinkedList 比较ArrayList 底层是数组结构,形如:而 LinkedList 则是链表结构:因为所采用的数据结构不同,所以在以下这些特性上存在区别:2 最佳实践(1)尽量使用接口一般情况下,尽量使用接口(List、Set 或 Map ),原创 2020-08-29 16:19:48 · 388 阅读 · 0 评论 -
说说 Java 迭代器
Java 迭代器是一个对象,它在一个序列中单向移动并可操作该序列中的每个元素对象。1 基本用法除了单向移动这个特性之外,还包含了获取、检查与移除元素的 API 方法。有了这些 API 方法,我们就可以迭代集合中的元素。代码示例中,首先通过 iterator() 方法返回迭代器对象,然后检查、获取集合中的元素。如果需要修改集合中的元素,那么可以先调用 next(),然后再修改这个元素。如果只是想遍历 List ,并不打算修改或删除 List 对象中原创 2020-08-29 16:18:28 · 198 阅读 · 0 评论 -
说说在 Java 中如何创建流
1 元素转换为流通过 Stream.of() ,我们可以很容易地将一组元素转化成流。Stream.of("今天", "是", "个", "好日子").forEach(System.out::println);System.out.println();Stream.of(23, 29.2, 291.8).forEach(System.out::println); 运行结果:今天是个好日子2329.2291.82 集合转换为流每种集合都可以通过调用&n原创 2020-07-25 11:45:16 · 455 阅读 · 0 评论 -
Tomcat 启动后,请求的 js 出现中文乱码的解决方法
1 原因因为win10系统的默认字符集是GBK,而 java 虚拟机在启动时,会读取该字符集。而我们的项目一般会设置为 UTF-8。而 Tomcat 本质上也是依赖于 JDK,所以自然会出现中文乱码。2 解决修改 Tomcat 安装路径的 bin 目录下 catalina.bat 文件:set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8"-D<name>=<value> 语法表示设置系统属性,它是一对键值对。这里其实是设置原创 2020-07-25 11:43:19 · 1739 阅读 · 0 评论 -
Java 流式编程概述
让我们首先从随机数说起。1 随机数真正的随机数是使用物理现象产生的,比如投掷钱币。这种随机数发生器叫做物理性随机数发生器。它的缺点是技术要求比较高。这幅图是芬兰的钱币。但这种通过物理性随机数发生器生成的真随机数,才是真正的随机,体现的是绝对的公平。伪随机数是有规律的,只不过这个规律周期比较长,但还是可以预测的。主要原因是伪随机数是计算机使用算法模拟出来的,因为这个过程并不涉及到物理过程,所以自然不可能具有真随机数的特性。目前用的比较广泛的有以下两种算法:线性同余算法周期:2^32= 4原创 2020-07-25 11:41:14 · 1013 阅读 · 0 评论