tk.mybatis与Activiti共存问题解决

由于tk.mybatis依赖了persistence-api,会让Activiti装配JpaProcessEngineAutoConfiguration,因为其@conditonalOnclass(name = “javax.persistence.EntityManagerFactory”)。

但实际没有使用JPA,导致启动报错。如果排除persistence-api,又会导致tk.mybatis报错。

参考了一番其它的人做法,无论是各种排除还是添加依赖都无效。

最终自己的解决方案是:

首先排除activiti jpa的自动装配:

1
@SpringBootApplication(exclude={JpaProcessEngineAutoConfiguration.class})。

然后找到activiti中的DataSourceProcessEngineAutoConfiguration.class 复制出源码,在自己的项目中添加一个同名文件(不同名也行)。然后粘贴内容到新建的文件中。最后删掉:

1
@ConditionalOnMissionClass(name = "javax.persistence.EntityManagerFactory")

Ok,搞定!

PriorityQueue解析

本文转载至github:https://github.com/CarpenterLee/JCFInternals/blob/master/markdown/8-PriorityQueue.md

PriorityQueue

总体介绍

前面以Java ArrayDeque为例讲解了StackQueue,其实还有一种特殊的队列叫做PriorityQueue,即优先队列。优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序(natural ordering),也可以通过构造时传入的比较器Comparator,类似于C++的仿函数)。

阅读更多

深入开源框架底层之ASM

什么是 ASM ?

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

阅读更多

从字节码来说明i++与++i到底有什么不同

看字节码之前需要先了解相关概念,如栈帧、操作数栈、局部变量表。
栈帧是JVM中很重要的一个概念,因为JVM是基于栈的架构。一个方法的调用其实就是栈帧入栈出栈的过程。栈顶栈帧就是当前方法调用。
一个栈帧中包含:

  1. 局部变量表
  2. 操作数栈
  3. 动态链接
  4. 方法返回地址
阅读更多

AbstractQueuedSynchronizer-随记

常见误区:Lock(乐观锁,自旋锁)一定比Synchronized好。这个说法是不正确的。自旋锁适合锁竞争不是很激烈的情况下使用,因为其使用了死循环,比较消耗CPU资源。Synchronized在JDK1.5后进行了优化,通过锁升级(偏向锁->轻量级锁(通常是自旋)->重量级锁) 提升了性能。

各种加密方式的问题

对称加密最大的问题就是密钥的传输问题。
于是乎出现了非对称加密。公钥完全公开,谁都可以使用。
非对称加密最大的问题就是身份确认的问题。
怎么能确认是不是正确的人使用公钥加密的信息呢。
于是乎出现了数字签名,使用对方公钥的人,用自己的私钥签名,然后对方用签名的人的公钥解密。

CountDownLatch-注意事项

先看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

CountDownLatch countDownLatch = new CountDownLatch(params.size());
try {
params.forEach(regionNameMapping -> {
CompletableFuture.runAsync(() -> {
Region region = this.getRegionById(regionNameMapping.getRegionId());
regionNameMapping.getRegionNameConsumer().accept(region.getName());
countDownLatch.countDown();
});
});
countDownLatch.await();
} catch (Exception e) {
log.error(e.getMessage(), e);
}

上面的代码逻辑很简单,并发去执行getRegionById这个方法。然后await等待结果。
但是里面有一个隐患,当region查出来为null时,会出现NPE,就会导致countDown()无法被执行,于是程序就一直阻塞在

1
2

countDownLatch.await();
阅读更多

获取jar中的文件注意事项

获取resources下的文件Java有很多种方法。但是如果你的程序最终打成jar发布。那么需要注意你是否以流inputstream读取。
因为jar中的文件路径为jar!xxxxxx 简单的使用path 或者getResouces肯定获取不到。