diff --git a/README.md b/README.md
index c1664f5..eaa7f67 100644
--- a/README.md
+++ b/README.md
@@ -85,4 +85,7 @@
1.1.0.0 | 新增注解@MakeReadWriteLocks 用于对类生成自定义读写锁,其fair 属性来自于注解的类下@ReadLock 注解或@WriteLock 注解的fair 属性值 | 2022年2月6日 |
+
+1.2.0.0 | 废弃@MakeReadWriteLocks 注解,现在不需要该注解也能正常识别自定义的锁;精简代码,提高编译速度 | 2022年2月6日 |
+
diff --git a/src/main/java/org/springframework/lock/annotation/MakeReadWriteLocks.java b/src/main/java/org/springframework/lock/annotation/MakeReadWriteLocks.java
deleted file mode 100644
index dfca0ef..0000000
--- a/src/main/java/org/springframework/lock/annotation/MakeReadWriteLocks.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.springframework.lock.annotation;
-
-import java.lang.annotation.*;
-
-/**
- * 自动生成读写锁
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Documented
-public @interface MakeReadWriteLocks {
-
- /**
- * 锁变量的名称,必须是合法变量名,并且不与已有变量声明重合
- * @return 默认无锁变量
- */
- String[] value() default {};
-}
diff --git a/src/main/java/org/springframework/lock/annotation/OptimisticLock.java b/src/main/java/org/springframework/lock/annotation/OptimisticLock.java
index b88558d..5705790 100644
--- a/src/main/java/org/springframework/lock/annotation/OptimisticLock.java
+++ b/src/main/java/org/springframework/lock/annotation/OptimisticLock.java
@@ -12,7 +12,7 @@
public @interface OptimisticLock {
/**
- * 乐观锁变量的名称
+ * 乐观锁变量的名称,该变量必须是合法变量名。如果与现有变量冲突,则替换掉现有变量
* @return 默认使用自动生成的锁
*/
String value() default "";
diff --git a/src/main/java/org/springframework/lock/annotation/ReadLock.java b/src/main/java/org/springframework/lock/annotation/ReadLock.java
index c58d5a7..2ce7820 100644
--- a/src/main/java/org/springframework/lock/annotation/ReadLock.java
+++ b/src/main/java/org/springframework/lock/annotation/ReadLock.java
@@ -15,13 +15,13 @@
public @interface ReadLock {
/**
- * 读写锁变量的名称,该变量必须是{@code ReentrantReadWriteLock}类的对象或其子类对象
+ * 读写锁变量的名称,该变量必须是合法变量名。如果与现有变量冲突,则替换掉现有变量
* @return 默认使用编译生成的
*/
String value() default "";
/**
- * 编译时生成的是否公平锁,该属性仅在{@code value}属性保持默认时才生效
+ * 是否为公平锁,同一把锁{@code fair}属性只需要写一次即可。如果{@code value}属性与现有变量冲突,则此处的{@code fair}属性将替换掉现有变量的{@code fair}属性
* @return 默认null,如果有自定义值则覆盖默认值
*/
BooleanEnum fair() default NULL;
diff --git a/src/main/java/org/springframework/lock/annotation/WriteLock.java b/src/main/java/org/springframework/lock/annotation/WriteLock.java
index 4f8e779..a0b3e79 100644
--- a/src/main/java/org/springframework/lock/annotation/WriteLock.java
+++ b/src/main/java/org/springframework/lock/annotation/WriteLock.java
@@ -15,13 +15,13 @@
public @interface WriteLock {
/**
- * 读写锁变量的名称,该变量必须是{@code ReentrantReadWriteLock}类的对象或其子类对象
+ * 读写锁变量的名称,该变量必须是合法变量名。如果与现有变量冲突,则替换掉现有变量
* @return 默认使用编译生成的
*/
String value() default "";
/**
- * 编译时生成的是否公平锁,该属性仅在{@code value}属性保持默认时才生效
+ * 是否为公平锁,同一把锁{@code fair}属性只需要写一次即可。如果{@code value}属性与现有变量冲突,则此处的{@code fair}属性将替换掉现有变量的{@code fair}属性
* @return 默认null,如果有自定义值则覆盖默认值
*/
BooleanEnum fair() default NULL;
diff --git a/src/main/java/org/springframework/lock/annotation/package-info.java b/src/main/java/org/springframework/lock/annotation/package-info.java
index 4822efd..c37189e 100644
--- a/src/main/java/org/springframework/lock/annotation/package-info.java
+++ b/src/main/java/org/springframework/lock/annotation/package-info.java
@@ -3,6 +3,6 @@
* 每个注解上都有对应的注释,写得很清楚,自己看就可以了,不加以赘述.
* 需要注意的是,如果需要使锁注解生效,需要在springboot启动类上添加{@code @EnableSpringLocks}注解
* @author 宗祥瑞
- * @version 1.0.0.0
+ * @version 1.2.0.0
*/
package org.springframework.lock.annotation;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/lock/aspect/OptimisticLockAspect.java b/src/main/java/org/springframework/lock/aspect/OptimisticLockAspect.java
index cdd5672..e8b8716 100644
--- a/src/main/java/org/springframework/lock/aspect/OptimisticLockAspect.java
+++ b/src/main/java/org/springframework/lock/aspect/OptimisticLockAspect.java
@@ -161,6 +161,7 @@ private static Thread findThread(long threadId) {
* @param waitTime 最长等待时长
* @param pollingTime 轮询周期
* @return 是否获得锁
+ * @throws InterruptedException 中断异常
*/
private boolean tryLock(AtomicLong lock, long waitTime, long pollingTime) throws InterruptedException {
long startWaitTime = System.currentTimeMillis();
diff --git a/src/main/java/org/springframework/lock/aspect/package-info.java b/src/main/java/org/springframework/lock/aspect/package-info.java
index bae4f54..e06378f 100644
--- a/src/main/java/org/springframework/lock/aspect/package-info.java
+++ b/src/main/java/org/springframework/lock/aspect/package-info.java
@@ -3,6 +3,6 @@
* 每个切面都有注释,没什么好说的,不加以赘述.
* 切面这部分需要托管到spring容器中去执行.
* @author 宗祥瑞
- * @version 1.0.0.0
+ * @version 1.2.0.0
*/
package org.springframework.lock.aspect;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/lock/enumeration/package-info.java b/src/main/java/org/springframework/lock/enumeration/package-info.java
index f1eac91..40c181b 100644
--- a/src/main/java/org/springframework/lock/enumeration/package-info.java
+++ b/src/main/java/org/springframework/lock/enumeration/package-info.java
@@ -1,7 +1,7 @@
/**
* 这是关于枚举类型的包.
* 写得很清楚,直接看代码就好了.
- * @version 1.0.0.0
+ * @version 1.2.0.0
* @author 宗祥瑞
*/
package org.springframework.lock.enumeration;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/lock/processor/OptimisticLockProcessor.java b/src/main/java/org/springframework/lock/processor/OptimisticLockProcessor.java
index 972ccda..21cdc14 100644
--- a/src/main/java/org/springframework/lock/processor/OptimisticLockProcessor.java
+++ b/src/main/java/org/springframework/lock/processor/OptimisticLockProcessor.java
@@ -80,7 +80,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
@Override
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement annotation : annotations) {
- Set cls = new HashSet();
Set extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
// 找到都有哪些类里面的方法用到了这个注解
Map> map = new HashMap>();
@@ -89,11 +88,10 @@ public boolean process(Set extends TypeElement> annotations, RoundEnvironment
String varName = method.getAnnotation(OptimisticLock.class).value();
TypeElement clz = (TypeElement) method.getEnclosingElement();
messager.printMessage(Diagnostic.Kind.NOTE, "发现需要包含注解" + annotation.getQualifiedName() + "的类" + clz.getQualifiedName());
- cls.add(clz);
map.computeIfAbsent(clz, k -> nil());
map.computeIfPresent(clz, (k, v) -> v.append(varName));
}
- for (TypeElement clz : cls) {
+ for (TypeElement clz : map.keySet()) {
List lockNames = map.get(clz);
if (lockNames.contains("")){
lockNames = List.filter(lockNames, "");
@@ -112,7 +110,7 @@ public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
JCVariableDecl var = (JCVariableDecl) jcTree;
if (locks.contains("" + var.name)) {
// 找到了类中的乐观锁,舍弃掉
- messager.printMessage(Diagnostic.Kind.NOTE, "已发现" + clz.getQualifiedName() + "类中的乐观锁" + var.name);
+ messager.printMessage(Diagnostic.Kind.WARNING, "已发现" + clz.getQualifiedName() + "类中的同名变量" + var.name + ", 将进行替换");
}else{
tree = tree.append(jcTree);
}
diff --git a/src/main/java/org/springframework/lock/processor/ReadWriteLockProcessor.java b/src/main/java/org/springframework/lock/processor/ReadWriteLockProcessor.java
index 9b669ab..606ffe3 100644
--- a/src/main/java/org/springframework/lock/processor/ReadWriteLockProcessor.java
+++ b/src/main/java/org/springframework/lock/processor/ReadWriteLockProcessor.java
@@ -9,9 +9,9 @@
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.*;
-import org.springframework.lock.annotation.MakeReadWriteLocks;
import org.springframework.lock.annotation.ReadLock;
import org.springframework.lock.annotation.WriteLock;
+import org.springframework.util.StringUtils;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
@@ -83,43 +83,36 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotations.size() == 0)
return Boolean.TRUE;
- Set cls = new HashSet();
- Map> map = new HashMap>();
+ Map> lockProperties = new HashMap>();
for (TypeElement annotation : annotations) {
Set extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
// 找到都有哪些类里面的方法用到了这个注解
for (Element element : elements) {
ExecutableElement method = (ExecutableElement) element;
TypeElement clz = (TypeElement) method.getEnclosingElement();
- messager.printMessage(Diagnostic.Kind.NOTE, "发现需要包含注解" + annotation.getQualifiedName() + "的类" + clz.getQualifiedName());
+ lockProperties.putIfAbsent(clz, new HashMap());
+ messager.printMessage(Diagnostic.Kind.NOTE, "发现包含注解" + annotation.getQualifiedName() + "的类" + clz.getQualifiedName());
Boolean isFair = null;
+ String lockName = null;
if (("" + annotation).equals("org.springframework.lock.annotation.ReadLock")) {
// 如果方法注解了读锁
isFair = method.getAnnotation(ReadLock.class).fair().getValue();
+ lockName = method.getAnnotation(ReadLock.class).value();
}
if (("" + annotation).equals("org.springframework.lock.annotation.WriteLock")) {
// 如果方法注解了写锁
isFair = method.getAnnotation(WriteLock.class).fair().getValue();
+ lockName = method.getAnnotation(WriteLock.class).value();
}
- if (isFair != null) {
- Boolean finalIsFair = isFair;
- map.put(clz, new HashMap(){{
- put("fair", finalIsFair);
- }});
- }else {
- if (map.get(clz) == null || map.get(clz).get("fair") == null){
- map.put(clz, new HashMap(){{
- put("fair", null);
- }});
- }
- }
- cls.add(clz);
+ if (!StringUtils.hasText(lockName))
+ lockName = "$lock";
+ if (isFair != null)
+ lockProperties.get(clz).put(lockName, isFair);
+ lockProperties.get(clz).putIfAbsent(lockName, null);
}
}
// 对每一个涉及到的类添加锁成员
- for (TypeElement clz : cls) {
- MakeReadWriteLocks makeReadWriteLocks = clz.getAnnotation(MakeReadWriteLocks.class);
- String[] makeLocks = makeReadWriteLocks != null ? makeReadWriteLocks.value() : new String[]{};
+ for (TypeElement clz : lockProperties.keySet()) {
JCTree tree = javacTrees.getTree(clz);
tree.accept(new TreeTranslator() {
@Override
@@ -127,29 +120,25 @@ public void visitClassDef(JCClassDecl jcClassDecl) {
// 在抽象树中过滤掉已有的的变量
List trees = nil();
for (JCTree x : jcClassDecl.defs) {
- if (x.getKind().equals(Kind.VARIABLE) && ("$lock".equals("" + ((JCVariableDecl) x).name) || "$readLock".equals("" + ((JCVariableDecl) x).name) || "$writeLock".equals("" + ((JCVariableDecl) x).name)))
+ if (x.getKind().equals(Kind.VARIABLE) && lockProperties.get(clz).containsKey("" + ((JCVariableDecl) x).name))
messager.printMessage(Diagnostic.Kind.WARNING, "已删除变量声明" + ((JCVariableDecl) x).name + ", 因为这个变量与生成的锁变量重名了");
else
trees = trees.append(x);
}
jcClassDecl.defs = trees;
- // 生成$读写锁
- messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁$lock");
- JCVariableDecl lock = makeReadWriteLock(clz, "$lock", map.get(clz));
- jcClassDecl.defs = jcClassDecl.defs.append(lock);
- messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读锁$readLock");
- JCVariableDecl readLock = makeReadLock(clz, "$readLock");
- jcClassDecl.defs = jcClassDecl.defs.append(readLock);
- messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成写锁$writeLock");
- JCVariableDecl writeLock = makeWriteLock(clz, "$writeLock");
- jcClassDecl.defs = jcClassDecl.defs.append(writeLock);
- // 生成make读写锁
- for (String makeLock : makeLocks) {
- if (makeLock.length() == 0)
- continue;
- messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁" + makeLock);
- JCVariableDecl make = makeReadWriteLock(clz, makeLock, map.get(clz));
- jcClassDecl.defs = jcClassDecl.defs.append(make);
+ // 生成读写锁
+ for (String varName : lockProperties.get(clz).keySet()) {
+ messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读写锁" + varName);
+ JCVariableDecl lock = makeReadWriteLock(clz, varName, lockProperties.get(clz).get(varName));
+ jcClassDecl.defs = jcClassDecl.defs.prepend(lock);
+ if ("$lock".equals(varName)){
+ messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读锁$readLock");
+ JCVariableDecl readLock = makeReadLock(clz, "$readLock");
+ jcClassDecl.defs = jcClassDecl.defs.append(readLock);
+ messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成写锁$writeLock");
+ JCVariableDecl writeLock = makeWriteLock(clz, "$writeLock");
+ jcClassDecl.defs = jcClassDecl.defs.append(writeLock);
+ }
}
super.visitClassDef(jcClassDecl);
@@ -163,26 +152,26 @@ public void visitClassDef(JCClassDecl jcClassDecl) {
* 制作读写锁
* @param clz 要添加锁的类
* @param lockName 变量名称
- * @param properties 注解的属性
+ * @param isFair 是否公平锁
* @return 变量声明
*/
- private JCVariableDecl makeReadWriteLock(TypeElement clz, String lockName, Map properties) {
+ private JCVariableDecl makeReadWriteLock(TypeElement clz, String lockName, Boolean isFair) {
// 导入包
JCCompilationUnit imports = (JCCompilationUnit) this.javacTrees.getPath(clz).getCompilationUnit();
imports.defs = imports.defs.append(this.treeMaker.Import(this.treeMaker.Select(this.treeMaker.Ident(names.fromString("java.util.concurrent.locks")), this.names.fromString("ReentrantReadWriteLock")), false));
// 声明变量
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE + Flags.FINAL);
- if (properties.get("fair") != null)
+ if (isFair != null)
return this.treeMaker.VarDef(
modifiers,
this.names.fromString(lockName),
this.memberAccess("java.util.concurrent.locks.ReentrantReadWriteLock"),
- this.treeMaker.NewClass(null, of(memberAccess("java.lang.Boolean")), treeMaker.Ident(names.fromString("ReentrantReadWriteLock")), of(this.treeMaker.Literal(properties.get("fair"))), null)
+ this.treeMaker.NewClass(null, of(memberAccess("java.lang.Boolean")), treeMaker.Ident(names.fromString("ReentrantReadWriteLock")), of(this.treeMaker.Literal(isFair)), null)
);
else
return this.treeMaker.VarDef(
modifiers,
- this.names.fromString("$lock"),
+ this.names.fromString(lockName),
this.memberAccess("java.util.concurrent.locks.ReentrantReadWriteLock"),
this.treeMaker.NewClass(null, nil(), treeMaker.Ident(names.fromString("ReentrantReadWriteLock")), nil(), null)
);
diff --git a/src/main/java/org/springframework/lock/processor/package-info.java b/src/main/java/org/springframework/lock/processor/package-info.java
index 31cc0c4..7a7d6c5 100644
--- a/src/main/java/org/springframework/lock/processor/package-info.java
+++ b/src/main/java/org/springframework/lock/processor/package-info.java
@@ -4,6 +4,6 @@
* 它的原理与lombok有些许类似,但代码风格比lombok更好理解,一看就懂
* 每个处理器都写了注释,写得都很清楚,不加以赘述
* @author 宗祥瑞
- * @version 1.0.0.0
+ * @version 1.2.0.0
*/
package org.springframework.lock.processor;
\ No newline at end of file
diff --git a/src/main/java/org/springframework/lock/timer/package-info.java b/src/main/java/org/springframework/lock/timer/package-info.java
index d4ed58c..a9fcbfb 100644
--- a/src/main/java/org/springframework/lock/timer/package-info.java
+++ b/src/main/java/org/springframework/lock/timer/package-info.java
@@ -3,6 +3,6 @@
* 意思就是在多长时间后执行什么功能,或者要求每过多长时间执行什么功能.
* java不能多继承,所以用内部类来实现
* @author 宗祥瑞
- * @version 1.0.0.0
+ * @version 1.2.0.0
*/
package org.springframework.lock.timer;
\ No newline at end of file
diff --git a/src/test/java/example/name/service/BaseService.java b/src/test/java/example/name/service/BaseService.java
index 69333d4..356f236 100644
--- a/src/test/java/example/name/service/BaseService.java
+++ b/src/test/java/example/name/service/BaseService.java
@@ -9,11 +9,6 @@
@Service
-@MakeReadWriteLocks({
- "myLock1",
- "myLock2",
- "myLock3"
-})
public class BaseService {
private static final Log LOGGER = LogFactory.getLog(BaseService.class);
@@ -102,10 +97,11 @@ public String testOptimisticLock2(){
return "testOptimisticLock2 执行结束";
}
- @ReadLock("myLock1")
+ @ReadLock(value = "myLock1", fair = FALSE)
public String testMakeLockRead(){
String name = Thread.currentThread().getName();
LOGGER.info(name + "开始执行");
+// System.out.println("" + myLock1.isFair());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {