Skip to content

Commit ce5e968

Browse files
committed
version 0.2.1.0 update
开发读锁注解,目前已实现注解编译期间添加读写锁
1 parent fcbd81a commit ce5e968

3 files changed

Lines changed: 90 additions & 17 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@
3434
<tr>
3535
<td>0.2.0.0</td><td>开发读锁注解,目前能通过注解获取内部已有的读锁</td><td>2022年1月28日</td>
3636
</tr>
37+
<tr>
38+
<td>0.2.1.0</td><td>开发读锁注解,目前已实现注解编译期间添加读写锁</td><td>2022年1月28日</td>
39+
</tr>
3740
</table>
Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,114 @@
11
package org.springframework.lock.processor;
22

33
import com.google.auto.service.AutoService;
4-
import com.sun.tools.javac.model.JavacElements;
4+
5+
import com.sun.source.tree.Tree;
6+
import com.sun.tools.javac.api.JavacTrees;
7+
import com.sun.tools.javac.code.Flags;
8+
import com.sun.tools.javac.code.Type;
59
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
610
import com.sun.tools.javac.tree.JCTree;
711
import com.sun.tools.javac.tree.TreeMaker;
8-
import com.sun.tools.javac.util.Context;
9-
import org.springframework.lock.annotation.ReadLock;
12+
import com.sun.tools.javac.tree.TreeTranslator;
13+
import com.sun.tools.javac.util.*;
1014

1115
import javax.annotation.processing.*;
1216
import javax.lang.model.SourceVersion;
1317
import javax.lang.model.element.Element;
18+
import javax.lang.model.element.ExecutableElement;
1419
import javax.lang.model.element.Name;
1520
import javax.lang.model.element.TypeElement;
16-
import javax.lang.model.type.TypeMirror;
17-
import javax.lang.model.util.Elements;
1821
import javax.tools.Diagnostic;
19-
import java.util.ArrayList;
22+
import java.util.HashSet;
2023
import java.util.Set;
24+
import java.util.concurrent.locks.ReentrantReadWriteLock;
2125

26+
import static com.sun.tools.javac.tree.JCTree.*;
27+
import static com.sun.tools.javac.util.List.nil;
2228

2329
@SupportedAnnotationTypes("org.springframework.lock.annotation.ReadLock")
2430
@SupportedSourceVersion(SourceVersion.RELEASE_8)
2531
@AutoService(Processor.class)
2632
public class ReadLockProcessor extends AbstractProcessor {
33+
34+
private Messager messager; // 编译时期输入日志的
35+
private JavacTrees javacTrees; // 提供了待处理的抽象语法树
36+
private TreeMaker treeMaker; // 封装了创建AST节点的一些方法
37+
private Names names; // 提供了创建标识符的方法
38+
39+
@Override
40+
public synchronized void init(ProcessingEnvironment processingEnv) {
41+
super.init(processingEnv);
42+
this.messager = processingEnv.getMessager();
43+
this.javacTrees = JavacTrees.instance(processingEnv);
44+
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
45+
this.treeMaker = TreeMaker.instance(context);
46+
this.names = Names.instance(context);
47+
}
48+
2749
@Override
2850
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
29-
Messager messager = this.processingEnv.getMessager();
3051
for (TypeElement annotation : annotations) {
3152
Name qualifiedName = annotation.getQualifiedName();
32-
messager.printMessage(Diagnostic.Kind.NOTE,"正在处理注解" + qualifiedName);
33-
// TODO 处理注解
53+
Set<TypeElement> cls = new HashSet<TypeElement>();
3454
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(annotation);
55+
// 找到都有哪些类里面的方法用到了这个注解
3556
for (Element element : elements) {
36-
// TODO 处理被注解的方法
37-
messager.printMessage(Diagnostic.Kind.NOTE,"-----------" + element.getSimpleName());
57+
ExecutableElement method = (ExecutableElement) element;
58+
TypeElement clz = (TypeElement) method.getEnclosingElement();
59+
messager.printMessage(Diagnostic.Kind.NOTE, "发现需要包含注解" + annotation.getQualifiedName() + "的类" + clz.getQualifiedName());
60+
cls.add(clz);
61+
}
62+
for (TypeElement clz : cls) {
63+
JCTree tree = javacTrees.getTree(clz);
64+
tree.accept(new TreeTranslator() {
65+
@Override
66+
public void visitClassDef(JCTree.JCClassDecl jcClassDecl) {
67+
// 在抽象树中找出所有的变量
68+
boolean foundLock = false;
69+
for (JCTree jcTree : jcClassDecl.defs) {
70+
if (jcTree.getKind().equals(Tree.Kind.VARIABLE)) {
71+
JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) jcTree;
72+
if ("java.util.concurrent.locks.ReadWriteLock".equalsIgnoreCase(var.vartype.type.toString()) || "java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock".equals(var.vartype.type.toString())) {
73+
// 找到了类中的读锁,不修改语法树
74+
messager.printMessage(Diagnostic.Kind.NOTE, "已发现" + clz.getQualifiedName() + "类中的读锁" + var.name);
75+
foundLock = true;
76+
break;
77+
}
78+
}
79+
}
80+
if (!foundLock){
81+
messager.printMessage(Diagnostic.Kind.NOTE, "将为类" + clz.getQualifiedName() + "动态生成读锁");
82+
// TODO 修改语法树
83+
JCVariableDecl lock = makeReadWriteLock();
84+
jcClassDecl.defs = jcClassDecl.defs.prepend(lock);
85+
}
86+
super.visitClassDef(jcClassDecl);
87+
}
88+
});
3889
}
39-
messager.printMessage(Diagnostic.Kind.NOTE,"处理注解完毕" + qualifiedName);
4090
break;
4191
}
4292
return Boolean.TRUE;
4393
}
94+
95+
private JCVariableDecl makeReadWriteLock(){
96+
JCModifiers modifiers = this.treeMaker.Modifiers(Flags.PRIVATE);
97+
JCVariableDecl var = this.treeMaker.VarDef(
98+
modifiers,
99+
this.names.fromString("lock"),
100+
this.memberAccess("java.util.concurrent.locks.ReentrantReadWriteLock"),
101+
this.treeMaker.NewClass(null, nil(), treeMaker.Ident(names.fromString("ReentrantReadWriteLock")), nil(), null)
102+
);
103+
return var;
104+
}
105+
106+
private JCExpression memberAccess(String components) {
107+
String[] componentArray = components.split("\\.");
108+
JCTree.JCExpression expr = treeMaker.Ident(this.names.fromString(componentArray[0]));
109+
for (int i = 1; i < componentArray.length; i++) {
110+
expr = treeMaker.Select(expr, this.names.fromString(componentArray[i]));
111+
}
112+
return expr;
113+
}
44114
}

src/test/java/example/name/service/BaseService.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ public class BaseService {
1414

1515
private static final Log LOGGER = LogFactory.getLog(BaseService.class);
1616

17-
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
18-
19-
private final Lock readLock = lock.readLock();
20-
21-
private final Lock writeLock = lock.writeLock();
17+
// private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
18+
//
19+
// private final Lock readLock = lock.readLock();
20+
//
21+
// private final Lock writeLock = lock.writeLock();
2222

2323
@Synchronized
2424
public String testSynchronized() {

0 commit comments

Comments
 (0)