2013-02-13 5 views
2

기본 생성자가없는 클래스에 대해 cglib을 사용하여 하위 클래스를 생성해야합니다.기본 생성자가없는 클래스의 하위 클래스를 생성하십시오.

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

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

새로운 클래스가 슈퍼 클래스에서 일부 비 기본 생성자를 호출 할 필요가 기본 생성자가 있어야합니다 나는 기본 생성자와 클래스에 대해 잘 작동 코드를 다음했다.

나는 cglib이 그런 일을 할 수 없다는 것을 조사한 결과 asm을 사용해야한다는 것을 발견했다. 그러나 클래스에 기본 생성자를 추가하는 예제를 찾을 수 없습니다.

누군가 구현 방법에 대한 예가 있으면 좋을 것입니다.

답변

3

이 문제가 해결되었습니다. 그것은 내가 상상했던 것보다 약간 다른 것처럼 보였다. 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; 
     } 
    } 

희망이 예 :

은 내가 가진 무엇 내가 한 것처럼 여러 시간을 보내지 않는 누군가를 도울 것입니다.