반응형

javax.annotation.processing.AbstractProcessor는 Java 어노테이션(Annotation)을 처리하는데 사용되는 추상 클래스(Abstract Class)입니다. 이 클래스를 상속하여 새로운 어노테이션 프로세서(Annotation Processor)를 만들 수 있습니다.

어노테이션 프로세서는 자바 컴파일러(Java Compiler)가 소스 코드를 컴파일할 때, 소스 코드 내부의 어노테이션 정보를 수집하고, 이 정보를 바탕으로 코드를 생성하거나 다른 처리를 수행합니다. 이를 통해, 개발자는 어노테이션을 이용해 코드를 보다 쉽고 간결하게 작성할 수 있습니다.

AbstractProcessor는 다음과 같은 메서드를 제공합니다.

1. process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) : 이 메서드는 컴파일러가 어노테이션 정보를 수집할 때마다 호출됩니다. annotations 매개변수에는 이번 라운드(Round)에서 처리할 어노테이션들의 집합이, roundEnv 매개변수에는 이번 라운드에서 처리할 요소(Element)들의 집합이 전달됩니다. 이 메서드에서는 요소들을 처리하고, 새로운 코드를 생성하거나 다른 처리를 수행합니다.

2. getSupportedAnnotationTypes() : 이 메서드는 이 어노테이션 프로세서가 처리할 수 있는 어노테이션의 이름을 반환합니다. 반환값은 문자열 배열(String[]) 형태로 지정합니다.

3. getSupportedSourceVersion() : 이 메서드는 이 어노테이션 프로세서가 지원하는 자바 소스 코드 버전을 반환합니다. 반환값은 SourceVersion 열거형(Enum) 형태로 지정합니다.

AbstractProcessor를 상속받아 새로운 어노테이션 프로세서를 만들 때는 다음과 같은 메서드를 오버라이드(Override)하여 구현합니다.

1. process() : 어노테이션 처리 로직을 구현합니다.

2. getSupportedAnnotationTypes() : 이 어노테이션 프로세서가 처리할 수 있는 어노테이션의 이름을 반환합니다.

3. getSupportedOptions() : 이 어노테이션 프로세서가 지원하는 옵션을 반환합니다.

4. getSupportedSourceVersion() : 이 어노테이션 프로세서가 지원하는 자바 소스 코드 버전을 반환합니다.

어노테이션 프로세서를 사용하여 코드를 생성하는 방법은 각각의 어노테이션 프로세서에 따라 다릅니다. 일반적으로는, JavaPoet 라이브러리를 사용하여 코드를 생성합니다. JavaPoet는 자바 코드를 생성하는 라이브러리이며, 코드를 생성하기 위한 API를 제공합니다. 이를 이용하여 AbstractProcessor에서 새로운 코드를 생성할 수 있습니다.

AbstractProcessor를 사용하는 경우, 다음과 같은 주의점이 있습니다.

1. 어노테이션 프로세서는 컴파일 타임(Compile Time)에 실행됩니다. 따라서, 프로세서가 사용하는 클래스나 라이브러리가 컴파일 환경에 존재해야 합니다.

2. 어노테이션 프로세서는 컴파일러의 메모리와 자원을 사용합니다. 따라서, 너무 많은 어노테이션 프로세서를 사용하거나, 프로세서에서 수행하는 작업이 매우 복잡하거나, 처리할 요소(Element)의 개수가 많은 경우, 컴파일 시간이 길어질 수 있습니다.

3. 어노테이션 프로세서를 사용할 때는, 대상 어노테이션을 잘 이해하고, 프로세서에서 처리해야 할 요소(Element)를 올바르게 추출해야 합니다. 이를 위해, Java의 표준 어노테이션 처리 API인 javax.lang.model.element 패키지를 잘 이해해야 합니다.

이와 같은 점들을 고려하여, AbstractProcessor를 사용하여 어노테이션 프로세서를 작성하면, 소스 코드를 보다 쉽고 간결하게 작성할 수 있습니다. 또한, 코드 생성 및 다른 처리 작업을 수행하여, 보다 높은 생산성과 코드 품질을 달성할 수 있습니다.물론입니다. 다음은 AbstractProcessor를 상속받아 간단한 어노테이션 프로세서를 작성하는 예제 코드입니다.

 

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
import java.util.Set;

@SupportedAnnotationTypes("com.example.MyAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class MyAnnotationProcessor extends AbstractProcessor {

    private Elements elementUtils;
    private Types typeUtils;
    private Filer filer;
    private Messager messager;

    @Override
    public void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        elementUtils = processingEnv.getElementUtils();
        typeUtils = processingEnv.getTypeUtils();
        filer = processingEnv.getFiler();
        messager = processingEnv.getMessager();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
            // MyAnnotation 어노테이션이 붙은 요소(Element)를 찾음
            if (element.getKind() == ElementKind.CLASS) {
                // 요소가 클래스(Class)인 경우에만 처리
                MyAnnotation annotation = element.getAnnotation(MyAnnotation.class);
                if (annotation != null) {
                    // MyAnnotation 어노테이션 정보를 가져옴
                    String message = annotation.value();
                    messager.printMessage(Kind.NOTE, "MyAnnotation: " + message, element);
                    // 요소에 대한 코드 생성 등의 처리 작업 수행
                }
            }
        }
        return true;
    }

}


이 예제 코드는 @MyAnnotation 어노테이션이 붙은 클래스를 찾아서 처리하는 간단한 어노테이션 프로세서입니다. init() 메서드에서는 ProcessingEnvironment 객체를 통해 유틸리티 클래스들을 가져옵니다.

process() 메서드에서는 MyAnnotation 어노테이션이 붙은 클래스를 찾아서 처리합니다. 이 예제 코드에서는 MyAnnotation 어노테이션 정보를 가져와서 출력하는 부분만 구현되어 있습니다. 요소에 대한 코드 생성 등의 처리 작업은 주석으로 처리되어 있습니다.

 

 

반응형

+ Recent posts