iT邦幫忙

DAY 24
1

Java Web的設計與應用系列 第 24

Day24 探討ASM-修改Bytecode或動態產生Class

  • 分享至 

  • xImage
  •  

準備技術:

  1. ASM
  2. Class Loader
  3. Reflection
  4. IOC/DI

當Java Class進入到JVM,是以Bytecode格式進入,ASM的目的是希望能夠修改Bytecode或動態產生Class。為什麼要修改Class?因為有這樣的機制,我們可以動態的將Clas加料,這是依賴注入。

如圖,針對Spring Container我們可以注入MetaData和POJO資料改變一些Class的結果,達到另一個功能實現的目的。

  1. 先看一個例子,我們想要寫一個Class觀看另一個Class的變數。變數有Static的,final的,以及非Static或Final的如String,還有double。

    public class ForReadClass {

     final int init = 110;
     private final Integer intField = 120;
     public final String stringField = "Public Final Strng Value";
     public static String commStr = "Common String value";
     String str = "Just a string value";
     final double d = 1.1;
     final Double D = 1.2;
    
     public ForReadClass() {
     }
    
     public void methodA() {
     	System.out.println(intField);
     }
    
     @SuppressWarnings("unchecked")
     public static void main(String[] args) {
    
     	  try { ClassReader reader = new ClassReader("core.ForReadClass");
     	  		ClassNode cn = new ClassNode(); reader.accept(cn, 0);
     	  			System.out.println(cn.name); List<FieldNode> fieldList = cn.fields;
     	  			for (FieldNode fieldNode : fieldList) {
     	  					System.out.println("Field name: " + fieldNode.name);
     	  					System.out.println("Field desc: " + fieldNode.desc);
     	  					System.out.println("Filed value: " + fieldNode.value);
     	  					System.out.println("Filed access: " + fieldNode.access); } 
     	  	} catch(IOException e) 
     	  			{ e.printStackTrace(); } 
     	  }
    

    }

  2. 程式執行之後,很明顯的,沒有抓到 非Static或Final系列的變數。

  3. 利用ASM的AbstractInNode方式抓到全部變數而看到,但是經由測試,Double變數沒抓到,這以後修改。

     public static void main(String[] args) {
    
    
     	try {
     		ClassReader reader = new ClassReader("core.ForReadClass");
     		ClassNode cn = new ClassNode();
     		reader.accept(cn, 0);
     		List<MethodNode> methodList = cn.methods;
     		for (MethodNode md : methodList) {
     			System.out.println(md.name);
     			System.out.println(md.access);
     			System.out.println(md.desc);
     			System.out.println(md.signature);
     			List<LocalVariableNode> lvNodeList = md.localVariables;
     			for (LocalVariableNode lvn : lvNodeList) {
     				System.out.println("Local name: " + lvn.name);
     				System.out.println("Local name: " + lvn.start.getLabel());
     				System.out.println("Local name: " + lvn.desc);
     				System.out.println("Local name: " + lvn.signature);
     			}
     			Iterator<AbstractInsnNode> instraIter = md.instructions.iterator();
     			while (instraIter.hasNext()) {
     				AbstractInsnNode abi = instraIter.next();
     				if (abi instanceof LdcInsnNode) {
     					LdcInsnNode ldcI = (LdcInsnNode) abi;
     					System.out.println("LDC node value: " + ldcI.cst);
     				}
     			}
     		}
     		MethodVisitor mv = cn.visitMethod(Opcodes.AALOAD, "<init>", Type
     				.getType(String.class).toString(), null, null);
     		mv.visitFieldInsn(Opcodes.GETFIELD,
     				Type.getInternalName(String.class), "str",
     				Type.getType(String.class).toString());
     		System.out.println(cn.name);
     		List<FieldNode> fieldList = cn.fields;
     		for (FieldNode fieldNode : fieldList) {
     			System.out.println("Field name: " + fieldNode.name);
     			System.out.println("Field desc: " + fieldNode.desc);
     			System.out.println("Filed value: " + fieldNode.value);
     			System.out.println("Filed access: " + fieldNode.access);
     			/*
     			if (fieldNode.visibleAnnotations != null) {
     				for (AnnotationNode	 anNode : 	fieldNode.visibleAnnotations) {
                         System.out.println(anNode.desc);
                     }
     			}
     			*/
     		}
     	} catch (IOException e) {
     		e.printStackTrace();
     	} catch (SecurityException e) {
     		e.printStackTrace();
     	} catch (IllegalArgumentException e) {
     		e.printStackTrace();
     	}
     }
    

    }

參考書籍:

  1. ASM官網
  2. Spring in IOC/DI

Day 24 結束


上一篇
Day23 JVM monitor 應用
下一篇
Day25 JAXB-載入xml去修改Class內容
系列文
Java Web的設計與應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言