大家知道ASM可以來分析 修改類 從前學(xué)習(xí)spring的時(shí)候里面有個(gè)叫IOC的技術(shù),不知道他的底層實(shí)現(xiàn)感覺很神秘,
我們提供的服務(wù)有:成都網(wǎng)站制作、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、贛州ssl等。為上1000+企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的贛州網(wǎng)站制作公司但是最近在看ASM的東西,感覺結(jié)合反射用它就可以實(shí)現(xiàn)自動(dòng)注入的功能。例子如下
那spring里面是如何實(shí)現(xiàn)的呢?
// 注解類 package hgs.asm; public @interface AutoWare { } //AnoDesc 里面的一個(gè)屬性 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); } } //測(cè)試 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); //得到所有的屬性 Listfields = 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 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(); } } 結(jié)果