大家知道ASM可以来分析 修改类 从前学习spring的时候里面有个叫IOC的技术,不知道他的底层实现感觉很神秘,
但是最近在看ASM的东西,感觉结合反射用它就可以实现自动注入的功能。例子如下
那spring里面是如何实现的呢?
//
注解类
package hgs.asm;
public @interface AutoWare {
}
//AnoDesc 里面的一个属性
package hgs.asm;
public class A {
}
package hgs.asm;
//用于操作的类
public class AnoDesc {
String name = "hgs";
int age = 100;
@AutoWare
A a;
public void saySomething(String desc) {
System.out.println("say:" + desc);
}
}
//测试
package hgs.asm;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
public class Test {
public static void test1() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
String clazz = "hgs.asm.AnoDesc";
Class<?> forName = Class.forName(clazz);
AnoDesc newInstance = (AnoDesc)forName.newInstance();
//通过asm读取类 通过其属性api 来访问类的属性 方法 注解
ClassNode node = new ClassNode();
//node.superName ="org.objectweb.asm.ClassVisitor";
ClassReader reader = new ClassReader("hgs.asm.AnoDesc");
//ClassWriter writer = new ClassWriter(0);
reader.accept(node,0);
//node.accept(writer);
//得到所有的属性
List<FieldNode> fields = node.fields;
for(FieldNode fnd: fields) {
String name = fnd.name;
String desc = fnd.desc;
Object value = fnd.value;
Type tp = Type.getObjectType(desc);
System.out.println("name:"+name);
System.out.println("desc:"+desc);
System.out.println("value:"+value);
System.out.println("type:"+tp.getInternalName());
System.out.println();
//判断属性是否存在 AutoWare注解
List<AnnotationNode> invisibleAnnotations = fnd.invisibleAnnotations;
if(invisibleAnnotations!=null ) {
for(AnnotationNode and : invisibleAnnotations) {
System.out.println(" anotation:"+and.desc);
System.out.println("equals:"+"Lhgs/asm/AutoWare;".equals(and.desc));
//存在的话 就把该属性初始化
if("Lhgs/asm/AutoWare;".equals(and.desc)) {
String qiliName = tp.getInternalName().replaceFirst("L", "").replaceAll("/", "\\.").replace(";", "");
System.out.println("qulity name :"+ qiliName);
Class<?> fi = Class.forName(qiliName);
Field declaredField = forName.getDeclaredField(name);
declaredField.set(newInstance,fi.newInstance() );
}
}
}
}
System.out.println(newInstance.a);
}
public static void main(String[] args) throws Exception{
test1();
}
}
结果
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:http://blog.itpub.net/31506529/viewspace-2675782/