我需要使用cglib为没有默认构造函数的类生成子类。我有以下代码适用于默认构造函数的类:
Enhancer enhancer = new Enhancer();
enhancer.setCallbackType(NoOp.class);
enhancer.setUseCache(false);
enhancer.setSuperclass(clazz);
return enhancer.createClass();
新类应该有默认构造函数,需要从超类中调用一些非默认构造函数。
我搜索过并发现cglib不能做这些事情我需要使用asm。但是我找不到将默认构造函数添加到类的示例。
如果某人有一个如何实现它的例子,那就太好了。
答案 0 :(得分:3)
我解决了这个问题。它看起来有点像我以前想象的那样。 Cglib继承了所有构造函数,而不仅仅是我之前想到的默认构造函数。
然而,似乎我不能在不影响现有cglib构造函数构造代码的情况下替换构造函数。这是次要的意义,所以我只是从构造函数注入转移到方法注入。我在构造函数返回之前添加了我的方法调用。这有效!我很高兴。
这就是我得到的:
cglib Enhancer调用
Enhancer enhancer = new Enhancer();
enhancer.setNamingPolicy(new IndexedNamingPolicy());
enhancer.setCallbackType(NoOp.class);
enhancer.setUseCache(false);
enhancer.setStrategy(new DefaultGeneratorStrategy() {
@Override
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
return new TransformingClassGenerator(cg, new DefaultConstructorEmitter(key));
}
});
enhancer.setSuperclass(clazz);
return enhancer.createClass();
和我的DefaultConstructorEmitter(它仍然以构造函数处理命名,没关系)
private class DefaultConstructorEmitter extends ClassEmitterTransformer {
private final Signature CALL_SIGNATURE = TypeUtils.parseSignature("void someMethod(Object)");
private String parametersKey;
public DefaultConstructorEmitter(final String key) {
parametersKey = key;
}
@Override
public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
final CodeEmitter emitter = super.begin_method(access, sig, exceptions);
if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
return new CodeEmitter(emitter) {
@Override
public void visitInsn(int arg0) {
if (arg0 == Opcodes.RETURN) {
Type classType = ...
emitter.load_this();
emitter.push(parametersKey);
emitter.invoke_static(classType, CALL_SIGNATURE);
}
super.visitInsn(arg0);
}
};
}
return emitter;
}
}
希望这个例子能帮助别人像我一样花几个小时。