??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美天堂在线,国产成人一区二区三区小说,成人三级在线http://blogjava.net/DLevin/category/51678.htmlIn general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatrazh-cnThu, 13 Aug 2015 10:50:28 GMTThu, 13 Aug 2015 10:50:28 GMT60深入perf4j源码http://www.aygfsteel.com/DLevin/archive/2015/04/19/424527.htmlDLevinDLevinSun, 19 Apr 2015 05:35:00 GMThttp://www.aygfsteel.com/DLevin/archive/2015/04/19/424527.htmlhttp://www.aygfsteel.com/DLevin/comments/424527.htmlhttp://www.aygfsteel.com/DLevin/archive/2015/04/19/424527.html#Feedback1http://www.aygfsteel.com/DLevin/comments/commentRss/424527.htmlhttp://www.aygfsteel.com/DLevin/services/trackbacks/424527.html阅读全文

DLevin 2015-04-19 13:35 发表评论
]]>
深入ASM源码之ClassReader、ClassVisitor、ClassWriterhttp://www.aygfsteel.com/DLevin/archive/2014/06/25/414292.htmlDLevinDLevinWed, 25 Jun 2014 13:14:00 GMThttp://www.aygfsteel.com/DLevin/archive/2014/06/25/414292.htmlhttp://www.aygfsteel.com/DLevin/comments/414292.htmlhttp://www.aygfsteel.com/DLevin/archive/2014/06/25/414292.html#Feedback1http://www.aygfsteel.com/DLevin/comments/commentRss/414292.htmlhttp://www.aygfsteel.com/DLevin/services/trackbacks/414292.html概述ASM?Java中比较流行的用来d字节码的cdQ用来基于字节码层面对代码进行分析和转换。在d的过E中可以加入自定义的逻辑以增强或修改原来已编译好的字节码Q比如CGLIB用它来实现动态代理。ASM被设计用于在q行时对Javac进行生成和转换Q当然也包括ȝ处理。ASM短小_悍、且速度很快Q从而避免在q行时动态生成字节码或{换时对程序速度的媄响,又因为它体积yQ可以在很多内存受限的环境中使用?br />ASM的主要优势包括如下几个方面:
1. 它又一个很,但设计良好ƈ且模块化的APIQ且易于使用?br />2. 它具有很好的文档Qƈ且还有eclipse插g?br />3. 它支持最新的Java版本?br />4. 它短精悍、快速、健壮?br />5. 它又一个很大的用户C֌Q可以给新用h供支持?br />6. 它的开源许可允怽几乎以Q何方式来使用它?br />
关于ASM的详l文档可以参考:ASM 3.0QJava字节码引擎库Q写的很详细的一个文档?br />

ASM Core设计一?/span>

在ASM的核心实CQ它主要有以下几个类、接口(在org.objectweb.asm包中Q:
ClassReaderc:字节码的d与分析引擎。它采用cMSAX的事件读取机Ӟ每当有事件发生时Q调用注册的ClassVisitor、AnnotationVisitor、FieldVisitor、MethodVisitor做相应的处理?br />ClassVisitor接口Q定义在dClass字节码时会触发的事gQ如cd解析完成、注解解析、字D解析、方法解析等?br />AnnotationVisitor接口Q定义在解析注解时会触发的事Ӟ如解析到一个基本值类型的注解、enum值类型的注解、Array值类型的注解、注解值类型的注解{?br />FieldVisitor接口Q定义在解析字段时触发的事gQ如解析到字D上的注解、解析到字段相关的属性等?br />MethodVisitor接口Q定义在解析Ҏ时触发的事gQ如Ҏ上的注解、属性、代码等?br />
ClassWriterc:它实CClassVisitor接口Q用于拼接字节码?br />AnnotationWriterc:它实CAnnotationVisitor接口Q用于拼接注解相兛_节码?br />FieldWriterc:它实CFieldVisitor接口Q用于拼接字D늛兛_节码?br />MethodWriterc:它实CMethodVisitor接口Q用于拼接方法相兛_节码?br />
SignatureReaderc:对类定义、字D定义、方法定义?本地变量定义的签名的解析。Signature因范型引入,用于存储范型定义时的元数据(因ؓq些元数据在q行时会被擦除)?br />SignatureVisitor接口Q定义在解析Signature时会触发的事Ӟ?正常的Type参数、类或接口的边界{?br />SignatureWriterc:它实CSignatureVisitor接口Q用于拼接范型相兛_节码?br />
Attributec:字节码中属性的cL象?br />ByteVectorc:字节码二q制存储的容器?br />Opcodes接口Q?字节码指令的一些常量定义?br />Typec:cd相关的常量定义以及一些基于其上的操作?br />
他们之间的类囑օpd下:

ClassReader实现

ClassReader是ASM中最核心的实玎ͼ它用于读取ƈ解析Class字节码。类字节码格式可以具体参考:《Java字节码格式详??/a>?a href="http://www.aygfsteel.com/DLevin/archive/2011/09/05/358034.html">《Java字节码格式详??/a>?a href="http://www.aygfsteel.com/DLevin/archive/2011/09/05/358035.html">《Java字节码格式详??/a>

在构建ClassReader实例Ӟ它首先保存字节码二进制数lbQ然后创建items数组Q数l的长度在字节码数组的第8?个字节指定(最前面4个字节是数CAFEBABEQ之?个字节是ơ版本号Q再?个字节是ȝ本号Q,每个item表示帔R池项在字节码数组的偏U量?Q常量池中每个项?个字节的type和紧跟的字节数组表示Q常量池Ҏ12U类型,其中CONSTANT_FieldRef_Info、CONSTANT_MethodRef_Info、CONSTANT_InterfaceMethodRef_Info、CONSTANT_NameAndType_Info包括其类型字节占?个字节,另外4个字节每2个字节ؓ字段、方法等所在的cR其名称、描q符在当前常量池中CONSTANT_Utf8_Infocd的引用;CONSTANT_Integer_Info、CONSTANT_Float_Info包括其类型字节占?个字节,另外四个字节为其对应的|CONSTANT_Class_Info、CONSTANT_String_Info包括其类型字节占?个字节,另外两个字节为在当前帔R池CONSTANT_Utf8_Info的索引QCONSTANT_Utf8_InfocdW?个字节表C类型,W??个字节ؓ该项所表示的字W串的长度)QCONSTANT_Double_Info、CONSTANT_Long_Info加类型字节ؓ9个字QmaxStringLength表示最长的UTF8cd的常量池的|用于军_在解析CONSTANT_Utf8_InfocdҎ最大需要的字符数组Qheader表示帔R池之后的字节码的W一个字节?br />
在调用ClassReader的acceptҎӞ它解析字节码中常量池之后的所有元素。紧接着帔R池的2个字节是该类的access标签QACC_PUBLIC、ACC_FINAL{;之后2个字节ؓ当前cd在常量池CONSTANT_Utf8_Infocd的烦引;之后2个字节ؓ其父cd在常量池CONSTANT_Utf8_Infocd的烦引(索引?表示父类为nullQ即直接l承自Objectc)Q再之后为其实现的接口数长度和对应各个接口名在常量池中CONSTANT_Utf8_Infocd的烦引|暂时先蟩qField和Method定义信息Q解析类的attribute表,它用两个字节表达attribute数组的长度,每个attribute中最前面2个字节是attribute名称QSourceFileQ读取sourceFile|、InnerClassesQ暂时纪录v始烦引)、EnclosingMethodQ纪录当前匿名类、本地类包含者类名以及包含者的Ҏ名和描述W)、SignatureQ类的签名信息,用于范型Q、RuntimeVisibleAnnotationsQ暂时纪录v始烦引)、DeprecatedQ表识属性)、SyntheticQ标识属性)、SourceDebugExtensionQؓ调试器提供的自定义扩展信息,d成一个字W串Q、RuntimeInvisibleAnnotationsQ暂时纪录v始烦引)Q对其他不识别的属性,U录成Attribute链,如果attribute名称W合在accept中attribute数组中指定的attribute名,则替换传入的attribute数组对应的项Q根据解析出来的信息调用以下visitҎQ?br />
void visit(int version, int access, String name, String signature, String superName, String[] interfaces);
// sourceFile, sourceDebug
void visitSource(String source, String debug);
// EnclosingMethod attribute: enclosingOwner, enclosingName, enclosingDesc. 
// Note: only when the class has EnclosingMethod attribute, meaning the class is a local class or an anonymous class
void visitOuterClass(String owner, String name, String desc);

依次解析RuntimeVisibleAnnotations和RuntimeInvisibleAnnotations属性,首先解析定义的Annotation的描q符以及q行时可见flagQ返回用戯定义的AnnotationVisitorQ?br />
AnnotationVisitor visitAnnotation(String desc, boolean visible);
Ҏ个定义的AnnotationQ解析其键值对QƈҎ不同的Annotation字段D用AnnotationVisitor中的ҎQ在所有解析结束后Q调用AnnotationVisitor.visitEndҎQ?br />
public interface AnnotationVisitor {
    // 对基本类型的数组Q依焉用该ҎQvisitArray只是在非基本cd时调用?/span>
    void visit(String name, Object value);
    void visitEnum(String name, String desc, String value);
    AnnotationVisitor visitAnnotation(String name, String desc);
    AnnotationVisitor visitArray(String name);

    void visitEnd();
}

之前解析出的attribute链表Q非标准的Attribute定义Q,Ҏ个Attribute实例Q调用ClassVisitor中的visitAttributeҎQ?br />
void visitAttribute(Attribute attr);
Attributecd含type字段和一个字节数l:
public class Attribute {
    public final String type;
    byte[] value;
    Attribute next;
}

Ҏ个InnerClasses属性,解析q调用ClassVisitor的visitInnerClassҎQ该属性事实上保存了所有其直接内部cM及它本n到最层cȝ路径Q:
void visitInnerClass(String name, String outerName, String innerName, int access);

解析字段Q它紧跟接口数组定义之后Q最前面?个字节ؓ字段数组的长度,Ҏ个字D,前面2个字节ؓ讉Kflag定义Q再?个字节ؓName索引Q以?个字节的描述W烦引,然后解析其Attribute信息QConstantValue、Signature、Deprecated、Synthetic、RuntimeVisibleAnnotations、RuntimeInvisibleAnnotations以及非标准定义的Attribute链,而后调用ClassVisitor的visitFieldҎQ返回FieldVisitor实例Q?br />
// 其中value为静态字D늚初始化|寚w静态字D,它的初始化必ȝ构造函数实玎ͼQ如果没有初始化|该gؓnull?/span>
FieldVisitor visitField(int access, String name, String desc, String signature, Object value);
对返回的FieldVisitor依次对其Annotation以及非标准Attribute解析Q调用其visitҎQƈ在完成后调用它的visitEndҎQ?br />
public interface FieldVisitor {
    AnnotationVisitor visitAnnotation(String desc, boolean visible);
    void visitAttribute(Attribute attr);
    void visitEnd();
}

解析Ҏ定义Q它紧跟字段定义之后Q最前面?个字节ؓҎ数组长度Q对每个ҎQ前?个字节ؓ讉Kflag定义Q再?个字节ؓName索引Q以?个字节的Ҏ描述W烦引,然后解析其Attribute信息QCode、Exceptions、Signature、Deprecated、RuntimeVisibleAnnotations、AnnotationDefault、Synthetic、RuntimeInvisibleAnnotations、RuntimeVisibleParameterAnnotations、RuntimeInvisibleParameterAnnotations以及非标准定义的Attribute链,如果存在Exceptions属性,解析其异常类数组Q之后调用ClassVisitor的visitMethodҎQ返回MethodVisitor实例Q?br />
MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions);

AnnotationDefault为对Annotation定义时指定默认值的解析Q然后依ơ解析RuntimeVisibleAnnotations、RuntimeInvisibleAnnotations、RuntimeVisibleParameterAnnotations、RuntimeInvisibleParameterAnnotations{属性,调用相关AnnotationVisitor的visitҎQ对非标准定义的Attribute链,依次调用MethodVisitor的visitAttributeҎQ?br />
public interface MethodVisitor {
    AnnotationVisitor visitAnnotationDefault();
    AnnotationVisitor visitAnnotation(String desc, boolean visible);
    AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible);
    void visitAttribute(Attribute attr);
}

对Code属性解析,d2个字节的最深栈大小、最大local变量数、code占用字节敎ͼ调用MethodVisitor的visitCode()Ҏ表示开始解析Code属性,Ҏ条指令,创徏一个Label实例q构成Label数组Q解析Code属性中的异常表Q对每个异常,调用visitTryCatchBlockҎQ?br />
void visitTryCatchBlock(Label start, Label end, Label handler, String type);
Label包含以下信息Q?br />
/**
 * A label represents a position in the bytecode of a method. Labels are used
 * for jump, goto, and switch instructions, and for try catch blocks.
 * 
 * 
@author Eric Bruneton
 
*/
public class Label {
    public Object info;
    int status;
    int line;
    int position;
    private int referenceCount;
    private int[] srcAndRefPositions;
    int inputStackTop;
    int outputStackMax;
    Frame frame;
    Label successor;
    Edge successors;
    Label next;
}
解析Code属性中的内部属性信息:LocalVariableTable、LocalVariableTypeTable、LineNumberTable、StackMapTable、StackMap以及非标准定义的Attribute链,Ҏ个Label调用其visitLineNumberҎ以及Ҏ个Frame调用visitFrameҎQƈ且对相应的指令调用相应的ҎQ?br />
void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack);
// Visits a zero operand instruction.

void visitInsn(int opcode);
// Visits an instruction with a single int operand.
void visitIntInsn(int opcode, int operand);
// Visits a local variable instruction. A local variable instruction is an instruction that loads or stores the value of a local variable.
void visitVarInsn(int opcode, int var);
// Visits a type instruction. A type instruction is an instruction that takes the internal name of a class as parameter.
void visitTypeInsn(int opcode, String type);
// Visits a field instruction. A field instruction is an instruction that loads or stores the value of a field of an object.
void visitFieldInsn(int opcode, String owner, String name, String desc);
// Visits a method instruction. A method instruction is an instruction that invokes a method.
void visitMethodInsn(int opcode, String owner, String name, String desc);
// Visits a jump instruction. A jump instruction is an instruction that may jump to another instruction.
void visitJumpInsn(int opcode, Label label);
// Visits a label. A label designates the instruction that will be visited just after it.
void visitLabel(Label label);
// Visits a LDC instruction.
void visitLdcInsn(Object cst);
// Visits an IINC instruction.
void visitIincInsn(int var, int increment);
// Visits a TABLESWITCH instruction.
void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels);
// Visits a LOOKUPSWITCH instruction.
void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels);
// Visits a MULTIANEWARRAY instruction.
void visitMultiANewArrayInsn(String desc, int dims);
// Visits a try catch block.
void visitTryCatchBlock(Label start, Label end, Label handler, String type);
void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index);
// Visits a line number declaration.
void visitLineNumber(int line, Label start);
// Visits the maximum stack size and the maximum number of local variables of the method.
void visitMaxs(int maxStack, int maxLocals);


最后调用ClassVisitor的visitEndҎQ?br />
void visitEnd();

ClassWriter实现

ClassWriterl承自ClassVisitor接口Q可以用它调用其相应的visitҎ动态的构造一个字节码cR它包含以下字段信息Q?br />
public class ClassWriter implements ClassVisitor {
    //The class reader from which this class writer was constructed, if any.
    ClassReader cr;
    //Minor and major version numbers of the class to be generated.
    int version;
    //Index of the next item to be added in the constant pool.
    int index;
    //The constant pool of this class.
    final ByteVector pool;
    //The constant pool's hash table data.
    Item[] items;
    //The threshold of the constant pool's hash table.
    int threshold;
    //A reusable key used to look for items in the {@link #items} hash table.
    final Item key;
    //A reusable key used to look for items in the {@link #items} hash table.
    final Item key2;
    //A reusable key used to look for items in the {@link #items} hash table.
    final Item key3;
    //A type table used to temporarily store internal names that will not necessarily be stored in the constant pool. 
    Item[] typeTable;
    //Number of elements in the {@link #typeTable} array.
    private short typeCount;
    //The access flags of this class.
    private int access;
    //The constant pool item that contains the internal name of this class.
    private int name;
    //The internal name of this class.
    String thisName;
    //The constant pool item that contains the signature of this class.
    private int signature;
    //The constant pool item that contains the internal name of the super class of this class.
    private int superName;
    // Number of interfaces implemented or extended by this class or interface.
    private int interfaceCount;
    //The interfaces implemented or extended by this class or interface. 
    private int[] interfaces;
    //The index of the constant pool item that contains the name of the source file from which this class was compiled.
    private int sourceFile;
    //The SourceDebug attribute of this class.
    private ByteVector sourceDebug;
    //The constant pool item that contains the name of the enclosing class of this class.
    private int enclosingMethodOwner;
    //The constant pool item that contains the name and descriptor of the enclosing method of this class.
    private int enclosingMethod;
    //The runtime visible annotations of this class.
    private AnnotationWriter anns;
    //The runtime invisible annotations of this class.
    private AnnotationWriter ianns;
    //The non standard attributes of this class.
    private Attribute attrs;
    //The number of entries in the InnerClasses attribute.
    private int innerClassesCount;
    //The InnerClasses attribute.
    private ByteVector innerClasses;
    //The fields of this class. These fields are stored in a linked list of {@link FieldWriter} objects, linked to each other by their {@link FieldWriter#next} field. This field stores the first element of this list.
    FieldWriter firstField;
    //This field stores the last element of this list.
    FieldWriter lastField;
    //The methods of this class. These methods are stored in a linked list of {@link MethodWriter} objects, linked to each other by their {@link MethodWriter#next} field. This field stores the first element of this list.
    MethodWriter firstMethod;
    //This field stores the last element of this list.
    MethodWriter lastMethod;
    //true if the maximum stack size and number of local variables must be automatically computed.
    private final boolean computeMaxs;
    //true if the stack map frames must be recomputed from scratch.
    private final boolean computeFrames;
   //true if the stack map tables of this class are invalid. 
    boolean invalidFrames;
}



DLevin 2014-06-25 21:14 发表评论
]]>
վ֩ģ壺 ľ| | | ɽ| | ³ƶ| | | ˮ| | | | | Ͻ| Խ| | | | ԰| Ͻ| ¤| ̨| ƽɽ| Դ| | ͺ| | | | | ͨ| ʡ| | | û| Ԫ| | ٷ| | | ¡|