add AsmAnnotationUtils

This commit is contained in:
hengyunabc 2020-05-04 14:00:38 +08:00
parent 99ff54f375
commit 82a3d69cc3
2 changed files with 155 additions and 0 deletions

View File

@ -0,0 +1,77 @@
package com.taobao.arthas.bytekit.utils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AnnotationNode;
/**
*
* @author hengyunabc 2020-05-04
*
*/
public class AsmAnnotationUtils {
public static List<String> queryAnnotationInfo(List<AnnotationNode> annotations, String annotationType,
String key) {
List<String> result = new ArrayList<String>();
if (annotations != null) {
for (AnnotationNode annotationNode : annotations) {
if (annotationNode.desc.equals(annotationType)) {
if (annotationNode.values != null) {
Iterator<Object> iterator = annotationNode.values.iterator();
while (iterator.hasNext()) {
String name = (String) iterator.next();
Object values = iterator.next();
if (key.equals(name)) {
result.addAll((List<String>) values);
}
}
}
}
}
}
return result;
}
public static void addAnnotationInfo(List<AnnotationNode> annotations, String annotationType, String key,
String value) {
AnnotationNode annotationNode = null;
for (AnnotationNode tmp : annotations) {
if (tmp.desc.equals(annotationType)) {
annotationNode = tmp;
}
}
if (annotationNode == null) {
annotationNode = new AnnotationNode(annotationType);
annotations.add(annotationNode);
}
if (annotationNode.values == null) {
annotationNode.values = new ArrayList<Object>();
}
// 查找有没有对应的key
String name = null;
List<String> values = null;
Iterator<Object> iterator = annotationNode.values.iterator();
while (iterator.hasNext()) {
if (key.equals(iterator.next())) {
values = (List<String>) iterator.next();
} else {
iterator.next();
}
}
if (values == null) {
values = new ArrayList<String>();
annotationNode.values.add(key);
annotationNode.values.add(values);
}
if (!values.contains(values)) {
values.add(value);
}
}
}

View File

@ -0,0 +1,78 @@
package com.taobao.arthas.bytekit.utils;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Arrays;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.springframework.stereotype.Service;
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
import com.alibaba.arthas.deps.org.objectweb.asm.tree.ClassNode;
import com.taobao.arthas.bytekit.utils.AsmAnnotationUtils;
import com.taobao.arthas.bytekit.utils.AsmUtils;
/**
*
* @author hengyunabc 2020-05-04
*
*/
public class AsmAnnotationUtilsTest {
@Target(value = { ElementType.TYPE, ElementType.METHOD })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AdviceInfo {
public String[] adviceInfos();
}
@Service
@AdviceInfo(adviceInfos = { "xxxx", "yyy" })
static class AAA {
@AdviceInfo(adviceInfos = { "mmm", "yyy" })
public void test() {
}
}
@Service
static class BBB {
public void test() {
}
}
@Test
public void test() throws IOException {
ClassNode classNodeA = AsmUtils.loadClass(AAA.class);
ClassNode classNodeB = AsmUtils.loadClass(BBB.class);
Assertions.assertThat(AsmAnnotationUtils.queryAnnotationInfo(classNodeA.visibleAnnotations,
Type.getDescriptor(AdviceInfo.class), "adviceInfos")).isEqualTo(Arrays.asList("xxxx", "yyy"));
AsmAnnotationUtils.addAnnotationInfo(classNodeA.visibleAnnotations, Type.getDescriptor(AdviceInfo.class),
"adviceInfos", "fff");
Assertions
.assertThat(AsmAnnotationUtils.queryAnnotationInfo(classNodeA.visibleAnnotations,
Type.getDescriptor(AdviceInfo.class), "adviceInfos"))
.isEqualTo(Arrays.asList("xxxx", "yyy", "fff"));
Assertions.assertThat(AsmAnnotationUtils.queryAnnotationInfo(classNodeB.visibleAnnotations,
Type.getDescriptor(AdviceInfo.class), "adviceInfos")).isEmpty();
AsmAnnotationUtils.addAnnotationInfo(classNodeB.visibleAnnotations, Type.getDescriptor(AdviceInfo.class),
"adviceInfos", "fff");
Assertions.assertThat(AsmAnnotationUtils.queryAnnotationInfo(classNodeB.visibleAnnotations,
Type.getDescriptor(AdviceInfo.class), "adviceInfos")).isEqualTo(Arrays.asList("fff"));
}
}