2011-03-24 3 views
2

나는 asm 프레임 워크의 ClassAdapter을 사용하여 바이트 코드 변환기를 작성하고 있습니다. 클래스에 커스텀 어노테이션이있는 경우, 메소드를 추가해 클래스가 인터페이스를 구현하도록 (듯이)하고 싶습니다. 메소드를 추가하는 것은 정상적으로 작동하지만 클래스를 인터페이스로 구현하는 것이 가장 좋은 방법인지 궁금합니다. visitAnnotationvisit 이후에만 호출되므로, 그때까지 수퍼 방문 메서드를 호출하고 필요한 모든 정보를 버퍼링하는 것을 지연해야합니다.주석이있는 경우 변환 된 클래스에 인터페이스 추가

비슷한 것을 구현 한 사람이 있습니까? 가능한 경우 패키지 문서에서이를 피할 것을 권장하지만이 경우 asm의 트리 API를 사용해야합니까?

public class MyClassAdapter extends ClassAdapter { 
    private String classname; 
    private boolean instrument; 

    public PropertyChangeSupportAdapter(ClassVisitor cv) { 
     super(cv); 
    } 

    @Override 
    public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { 
     super.visit(version, access, name, signature, superName, interfaces); 
     this.classname = name; 
    } 

    @Override 
    public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { 
     if (desc.equals("Lmypackage/MyAnnotation;")) { 
      instrument = true; 
      System.out.println("Instrumenting " + classname); 
     } 
     return super.visitAnnotation(desc, visible); 
    } 

    @Override 
    public void visitEnd() { 
     if (instrument) { 
      // add methods 
     } 
    } 
} 

답변

2

I는 ClassNode 및 ClassAdapter API를 조합하여 끝났다

여기서 변환의 일반적인 구조이다. 먼저 클래스 파일은 ClassNode로 해석된다

ClassReader cr = new ClassReader(inputStream); 
ClassNode cn = new ClassNode(); 
cr.accept(cn, 0); 

는 그런 다음 cn.visibleAnnotation 또는 cn.invisibleAnnotations 내 주석을 포함 처리 여부도 클래스가 이미 내가 추가 할 인터페이스를 구현하는지 확인하는 것이 가능하다. 이 경우 두 번째 단계는 건너 뛸 수 있습니다. ClassNode는 다음 문제로 ClassAdapter API를 사용하여 변환 할 수 있습니다

:

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); 
CheckClassAdapter ca = new CheckClassAdapter(cw); 
ClassVisitor cv = new PropertyChangeSupportAdapter(ca); 
cn.accept(cv); 

내 질문의 이유였다 package documentation에서 메모, 이러한 API 사이에 큰 성능 차이를 언급

ClassNode보다 ClassAdapter를 사용하여 클래스를 읽고 수정하는 속도가 거의 2 배 빠릅니다. ... 가능할 때이 클래스 어댑터를 사용하지 않는 것이 좋습니다.

다시 읽은 후 차이점은 ClassNode를 사용하여 바이트 코드를 조작 한 것으로 보입니다. 그러나이 하이브리드 솔루션을 벤치마킹하지 않았습니다.

관련 문제