//动态代理创建的class文件存储到本地
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"d:\\code");
//通过cglib动态代理获取代理对象的过程,创建调用的对象,在后续创建过程中EnhanceKey的对象,所以在进行enhancer对象创建的时候需要把EnhancerKey(newInstance)对象准备好,恰好这个对象也需要动态代理来生成
Enhancer enhancer = new Enhancer();
//设置enhancer对象的父类
enhancer.setSuperclass(MyCalculator.class);
//设置enhancer的回调对象
enhancer.setCallback(new MyCglib());
//创建代理对象
MyCalculator myCalculator = (MyCalculator) enhancer.create();
//通过代理对象调用目标方法
myCalculator.add(1,1);
System.out.println(myCalculator.getClass());
看一下new Enhancer();这一步的调用记录:
generateClass:384, KeyFactory$Generator (org.springframework.cglib.core)
generate:25, DefaultGeneratorStrategy (org.springframework.cglib.core)
generate:390, AbstractClassGenerator (org.springframework.cglib.core)
apply:115, AbstractClassGenerator$ClassLoaderData$3 (org.springframework.cglib.core)
apply:113, AbstractClassGenerator$ClassLoaderData$3 (org.springframework.cglib.core)
call:54, LoadingCache$2 (org.springframework.cglib.core.internal)
run:266, FutureTask (java.util.concurrent)
createEntry:61, LoadingCache (org.springframework.cglib.core.internal)
get:34, LoadingCache (org.springframework.cglib.core.internal)
get:143, AbstractClassGenerator$ClassLoaderData (org.springframework.cglib.core)
create:340, AbstractClassGenerator (org.springframework.cglib.core)
create:246, KeyFactory$Generator (org.springframework.cglib.core)
create:192, KeyFactory (org.springframework.cglib.core)
使用key工厂创建出对应class的代理类,后面的KeyFactory_HASH_ASM_TYPE即代理类中创建HashCode方法的策略
create:162, KeyFactory (org.springframework.cglib.core)
<clinit>:105, Enhancer (org.springframework.cglib.proxy)
main:11, MyTest (com.mashibing.proxy.cglib)
generateClass:384, KeyFactory$Generator (org.springframework.cglib.core)
// 该方法为字节码写入方法 为最后一步
public void generateClass(ClassVisitor v) {
// 创建类写入聚合对象
ClassEmitter ce = new ClassEmitter(v);
//找到被代理类的newInstance方法 如果没有会报异常,由此可知,如果想用Generator代理类生成器,必须要有newInstance方法
Method newInstance = ReflectUtils.findNewInstance(keyInterface);
//如果被代理类的newInstance不为Object则报异常,此处我们代理的Enchaer.EnhancerKey newInstance方法返回值为Object
if (!newInstance.getReturnType().equals(Object.class)) {
throw new IllegalArgumentException("newInstance method must return Object");
}
// 找到newInstance方法的所有参数类型并当做成员变量
Type[] parameterTypes = TypeUtils.getTypes(newInstance.getParameterTypes());
// 1.创建类开始写入类头,版本号,访问权限,类名等通用信息
ce.begin_class(Constants.V1_8,
Constants.ACC_PUBLIC,
getClassName(),
KEY_FACTORY,
new Type[]{Type.getType(keyInterface)},
Constants.SOURCE_FILE);
// 2.写入无参构造方法
EmitUtils.null_constructor(ce);
// 3.写入newInstance方法
EmitUtils.factory_method(ce, ReflectUtils.getSignature(newInstance));
int seed = 0;
// 4.开始构造有参构造方法
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC,
TypeUtils.parseConstructor(parameterTypes),
null);
e.load_this();
// 4.1有参构造中调用父类构造方法,即super.构造方法()
e.super_invoke_constructor();
e.load_this();
// 4.2找到传入的定制器 例如一开始传入的hashCode方法定制器
List<FieldTypeCustomizer> fieldTypeCustomizers = getCustomizers(FieldTypeCustomizer.class);
// 4.3遍历成员变量即newInstance方法的所有参数
for (int i = 0; i < parameterTypes.length; i++) {
Type parameterType = parameterTypes[i];
Type fieldType = parameterType;
for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
fieldType = customizer.getOutType(i, fieldType);
}
seed += fieldType.hashCode();
// 4.3将这些参数全部声明到写入类中
ce.declare_field(Constants.ACC_PRIVATE | Constants.ACC_FINAL,
getFieldName(i),
fieldType,
null);
e.dup();
e.load_arg(i);
for (FieldTypeCustomizer customizer : fieldTypeCustomizers) {
customizer.customize(e, i, parameterType);
}
// 4.4设置每个成员变量的值 即我们常见的有参构造中的this.xx = xx
e.putfield(getFieldName(i));
}
// 设置返回值
e.return_value();
// 有参构造及成员变量写入完成
e.end_method();
// hash code
// 5.写入hashcode方法
e = ce.begin_method(Constants.ACC_PUBLIC, HASH_CODE, null);
int hc = (constant != 0) ? constant : PRIMES[(Math.abs(seed) % PRIMES.length)];
int hm = (multiplier != 0) ? multiplier : PRIMES[(Math.abs(seed * 13) % PRIMES.length)];
e.push(hc);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.hash_code(e, parameterTypes[i], hm, customizers);
}
e.return_value();
// hashcode方法结束
e.end_method();
// equals
// 6.写入equals方法
e = ce.begin_method(Constants.ACC_PUBLIC, EQUALS, null);
Label fail = e.make_label();
e.load_arg(0);
e.instance_of_this();
e.if_jump(CodeEmitter.EQ, fail);
for (int i = 0; i < parameterTypes.length; i++) {
e.load_this();
e.getfield(getFieldName(i));
e.load_arg(0);
e.checkcast_this();
e.getfield(getFieldName(i));
EmitUtils.not_equals(e, parameterTypes[i], fail, customizers);
}
e.push(1);
e.return_value();
e.mark(fail);
e.push(0);
e.return_value();
// equals方法结束
e.end_method();
// toString
// 7.写入toString方法
e = ce.begin_method(Constants.ACC_PUBLIC, TO_STRING, null);
e.new_instance(Constants.TYPE_STRING_BUFFER);
e.dup();
e.invoke_constructor(Constants.TYPE_STRING_BUFFER);
for (int i = 0; i < parameterTypes.length; i++) {
if (i > 0) {
e.push(", ");
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, APPEND_STRING);
}
e.load_this();
e.getfield(getFieldName(i));
EmitUtils.append_string(e, parameterTypes[i], EmitUtils.DEFAULT_DELIMITERS, customizers);
}
e.invoke_virtual(Constants.TYPE_STRING_BUFFER, TO_STRING);
e.return_value();
// toString方法结束
e.end_method();
// 类写入结束,至此类信息收集完成并全部写入ClassVisitor
ce.end_class();
}
通过这个方法生成Enhancer enhancer。
后续生成MyCalculator代理对象也是如此