生成没有默认构造函数的类的子类

问题描述:

我需要使用cglib为没有默认构造函数的类生成子类。我有以下代码类工作正常与默认构造函数:生成没有默认构造函数的类的子类

Enhancer enhancer = new Enhancer(); 
    enhancer.setCallbackType(NoOp.class); 
    enhancer.setUseCache(false); 

    enhancer.setSuperclass(clazz); 
    return enhancer.createClass(); 

新类应该有哪些需要从它的超类调用一些非默认构造函数默认构造函数。

我已经搜索并发现cglib不能做这样的事情,我需要使用asm。但是我找不到添加默认构造函数的例子。

如果有人有一个例子如何实现它,那会很好。

我解决了这个问题。它看起来有点不同于我以前的想象。 Cglib继承了所有的构造函数,而不仅仅是我之前想的默认构造函数。

但是它似乎不能替换构造函数而不影响现有的cglib构造函数构造代码。这是微不足道的暗示,所以我只是从构造函数注入转移到了方法注入。我在构造函数返回之前添加我的方法调用。这工作!我很高兴。

这是我得到:

CGLIB增强调用

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; 
     } 
    } 

希望这个例子将帮助别人像我一样不要花费几个小时。