Skip to content

Commit

Permalink
version 1.2.0.0 update
Browse files Browse the repository at this point in the history
废弃@MakeReadWriteLocks注解,现在不需要该注解也能正常识别自定义的锁;精简代码,提高编译速度
  • Loading branch information
ZongXR committed Feb 6, 2022
1 parent 7ad77c2 commit a2769c6
Show file tree
Hide file tree
Showing 14 changed files with 50 additions and 81 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,7 @@
<tr>
<td>1.1.0.0</td><td>新增注解<code>@MakeReadWriteLocks</code>用于对类生成自定义读写锁,其<code>fair</code>属性来自于注解的类下<code>@ReadLock</code>注解或<code>@WriteLock</code>注解的<code>fair</code>属性值</td><td>2022年2月6日</td>
</tr>
<tr>
<td>1.2.0.0</td><td>废弃<code>@MakeReadWriteLocks</code>注解,现在不需要该注解也能正常识别自定义的锁;精简代码,提高编译速度</td><td>2022年2月6日</td>
</tr>
</table>

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public @interface OptimisticLock {

/**
* 乐观锁变量的名称
* 乐观锁变量的名称,该变量必须是合法变量名。如果与现有变量冲突,则替换掉现有变量
* @return 默认使用自动生成的锁
*/
String value() default "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
* 每个注解上都有对应的注释,写得很清楚,自己看就可以了,不加以赘述.
* 需要注意的是,如果需要使锁注解生效,需要在springboot启动类上添加{@code @EnableSpringLocks}注解
* @author 宗祥瑞
* @version 1.0.0.0
* @version 1.2.0.0
*/
package org.springframework.lock.annotation;
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
* 每个切面都有注释,没什么好说的,不加以赘述.
* 切面这部分需要托管到spring容器中去执行.
* @author 宗祥瑞
* @version 1.0.0.0
* @version 1.2.0.0
*/
package org.springframework.lock.aspect;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* 这是关于枚举类型的包.
* 写得很清楚,直接看代码就好了.
* @version 1.0.0.0
* @version 1.2.0.0
* @author 宗祥瑞
*/
package org.springframework.lock.enumeration;
Original file line number Diff line number Diff line change
Expand Up @@ -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<TypeElement> cls = new HashSet<TypeElement>();
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
// 找到都有哪些类里面的方法用到了这个注解
Map<TypeElement, List<String>> map = new HashMap<TypeElement, List<String>>();
Expand All @@ -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<String> lockNames = map.get(clz);
if (lockNames.contains("")){
lockNames = List.filter(lockNames, "");
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -83,73 +83,62 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (annotations.size() == 0)
return Boolean.TRUE;
Set<TypeElement> cls = new HashSet<TypeElement>();
Map<TypeElement, Map<String, Object>> map = new HashMap<TypeElement, Map<String, Object>>();
Map<TypeElement, Map<String, Boolean>> lockProperties = new HashMap<TypeElement, Map<String, Boolean>>();
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<String, Boolean>());
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<String, Object>(){{
put("fair", finalIsFair);
}});
}else {
if (map.get(clz) == null || map.get(clz).get("fair") == null){
map.put(clz, new HashMap<String, Object>(){{
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
public void visitClassDef(JCClassDecl jcClassDecl) {
// 在抽象树中过滤掉已有的的变量
List<JCTree> 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);
Expand All @@ -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<String, Object> 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)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
* 它的原理与lombok有些许类似,但代码风格比lombok更好理解,一看就懂
* 每个处理器都写了注释,写得都很清楚,不加以赘述
* @author 宗祥瑞
* @version 1.0.0.0
* @version 1.2.0.0
*/
package org.springframework.lock.processor;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
* 意思就是在多长时间后执行什么功能,或者要求每过多长时间执行什么功能.
* java不能多继承,所以用内部类来实现
* @author 宗祥瑞
* @version 1.0.0.0
* @version 1.2.0.0
*/
package org.springframework.lock.timer;
8 changes: 2 additions & 6 deletions src/test/java/example/name/service/BaseService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@


@Service
@MakeReadWriteLocks({
"myLock1",
"myLock2",
"myLock3"
})
public class BaseService {

private static final Log LOGGER = LogFactory.getLog(BaseService.class);
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit a2769c6

Please sign in to comment.