以下基于BTrace1.2.2
[url]http://kenai.com/projects/btrace/downloads/directory/releases
[/url]
BTrace类的增强分两部分:
Agent载入之前已加载类的转换;
Agent载入之后新定义类的转换;
其中,Agent载入之前已加载类的转换在:
com.sun.btrace.agent.Main.handleNewClient(final Client client)方法中处理;
关键的处理步骤:
// 注册类转换器---即:ClassFileTransformer
client.registerTransformer();
// 获取所有已加载的类
Class[] classes = inst.getAllLoadedClasses();
// 对所有已加载的类进行过滤,挑选出BTrace脚本需要跟踪的类,
// 对于“+”标识的类,通过递归superClass和superInterfaces查找
if(client.isCandidate(c))list.add(c);
// 重转换已加载的需要跟踪的类---会导致之前注册的类转换器被调用,从而实现类的增强
inst.retransformClasses(classes);
~~~~~~~~~~~~~~
Agent载入之后新定义类的转换机制:
新定义的类的转换,当类被加载时,会自动触发ClassFileTransformer,从而实现类的转换。
这儿的难点是:如何实现“+”:即子类的查找匹配;
@OnMethod(clazz = "+my.Command", method = "execute")
原因是:我们知道ClassFileTransformer被触发的时机包括3种:
类定义之时:ClassLoader.defineClass();
类重定义之时:Instrumentation.redefineClasses()
类重转换之时:Instrumentation.retransformClasses(),Agent载入之前已加载类的转换就是通过这种方式实现的
而ClassLoader.defineClass()之时和后面两种时机最主要的差别是Class是否已经加载;
public byte[] transform(ClassLoader loader, final String cname,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer);
即:transform方法中classBeingRedefined是否为null
我们也知道类的字节码byte[] classfileBuffer中仅仅包含直接superClass和实现接口的字符串,
而不包含间接超类和间接接口,所以仅仅凭借字节码是无从进行“+”子类的匹配判断的。
这些superClass和接口的字符串必须连接后变成真正的Class对象,才能通过递归的方式匹配查找。
为了实现“+”的查找,BTrace额外提供了一个ClassFileTransformer,这个被称作clInitTransformer,
它的作用是对所有需要加载的类,在类的静态初始化部分增加下面的代码:
{
BTraceRuntime.retransform(Ljava/lang/String;Ljava/lang/Class;)
}
以达到类被初始化后,立即发生重转换;从而再次触发ClassFileTransformer的目的。
这就是BTrace中存在两个ClassFileTransformer的原因:
void registerTransformer() {
inst.addTransformer(clInitTransformer, false);
inst.addTransformer(this, true);
}
也是hasSubclassChecks变量存在的原因。---如果有“+”存在,就强制类的重转换。
分享到:
相关推荐
NULL 博文链接:https://sswh.iteye.com/blog/1820391
Java语言程序设计:JAVA_5-子类与继承.ppt
设计一个学生类Student和它的一个子类Undergraduate,要求如下: 1) Student类有name(姓名)、和age(年龄)属性,一个包含两个参数的构造方法,用于给name和age属性赋值,一个show()方法打印Student的属性信息 2) ...
设计一个名为Person的类和他的两个名为Student和Employee子类。Employee又有两个子类:教员类Faculty和职员类Staff。
利用C#反射将子类舍弃多余的属性转换为父类,用途比较少。
Day10:javaBean 介绍和父类子类转换 Day11:java 的抽象类和接口 Day12:String 类和字符编码介绍 Day13:正则表达式和包装类 Day14:java 的内部类 Day15:java 的集合类 Day16:java 的异常处理 Day17:Swing ...
本代码用类和子类实现了输出复数的功能。适合初学者参考学习
实现一个图形类以及子类,其可以描述基本图形的属性及必要方法。
java代码-使用java,解决一个长方形类Rectangle,一个子类长方体类,计算周长,面积,体积的源代码 ——学习参考资料:仅用于个人学习使用!
USB设备类及设备子类及接口采用的设备类协议
在 Interface Builder 中,插入一个常规标签,然后将其类设置为QALabel并更改垂直对齐方式,例如在您的视图控制器中。 QA背景视图 UIView子类,只是将bg.png显示为背景。 它的QABackgroundView在于您可以通过将所需...
构造函数顺序:父类、类成员变量、子类 析构正好反过来
抽象类与抽象方法由abstract修饰 abstract的使用注意 抽象方法没有方法体 ...2.继承抽象类的子类必须把抽象类中的所有抽象成员都重写(实现)(除非子类也是抽象类。) 3.抽象类就是为了重写→多态。
AZEmptyState:一个UIControl子类,可以轻松创建空状态
:以员工为父类,该类包含员工的基本信息:姓名、年龄、部门。创建两个子类
Allegro-Class(类)SubClass(子类)层功能介绍 .docx