0Pricing
Java Academy · 강의

컴파일 시점 주석 처리기

컴파일 시점에 소스 파일을 생성하거나 코드를 검증하는 AbstractProcessor를 작성합니다.

컴파일 시점 주석 처리기은(는) CoddyKit의 무료 Java Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Java Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

애너테이션 프로세서란 무엇인가요?

애너테이션 프로세서(APT — 애너테이션 처리 도구)는 컴파일 중에 실행됩니다. 소스 코드의 애너테이션을 검사하고 새 소스 파일, 리소스 파일을 생성하거나 컴파일러 오류 및 경고를 발생시킬 수 있습니다.

AbstractProcessor: 기본 클래스

javax.annotation.processing.AbstractProcessor를 확장합니다. 애너테이션이 지정된 요소를 처리하려면 process()를 재정의합니다. 지원되는 애너테이션과 Java 소스 버전을 선언합니다.

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;

@SupportedAnnotationTypes("com.example.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_17)
public class BuilderProcessor extends AbstractProcessor {
    @Override
    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        for (Element e : roundEnv.getElementsAnnotatedWith(GenerateBuilder.class)) {
            generateBuilder((TypeElement) e);
        }
        return true;
    }
    private void generateBuilder(TypeElement cls) { /* generate source */ }
}

프로세서 등록하기

정규화된 클래스 이름을 META-INF/services/javax.annotation.processing.Processor에 작성하여 프로세서를 등록합니다. 빌드 도구(Maven, Gradle)가 자동으로 이를 인식합니다.

# META-INF/services/javax.annotation.processing.Processor
com.example.BuilderProcessor

소스 파일 생성하기

processingEnv.getFiler().createSourceFile()을 사용하여 새 .java 파일을 작성합니다. 그러면 컴파일러가 동일한 라운드 또는 다음 라운드에서 생성된 파일을 컴파일합니다.

JavaFileObject file = processingEnv.getFiler()
    .createSourceFile("com.example.UserBuilder");
try (Writer w = file.openWriter()) {
    w.write("package com.example;\n");
    w.write("public class UserBuilder {\n");
    w.write("  // generated builder\n");
    w.write("}\n");
}

요소 모델 검사하기

애너테이션 프로세서는 Class가 아니라 Element를 사용하여 작업합니다. 소스는 아직 컴파일되지 않았기 때문입니다. TypeElement, VariableElement, ExecutableElement을 사용합니다.

TypeElement classElement = (TypeElement) element;
String className = classElement.getSimpleName().toString();
List<VariableElement> fields = classElement.getEnclosedElements().stream()
    .filter(e -> e.getKind() == ElementKind.FIELD)
    .map(e -> (VariableElement) e)
    .collect(Collectors.toList());

컴파일러 오류 출력하기

processingEnv.getMessager().printMessage()를 호출하여 오류, 경고 또는 메모를 출력합니다. 사용자 지정 제약 애너테이션이 컴파일 시점에 위반 사항을 알리는 방식입니다.

processingEnv.getMessager().printMessage(
    Diagnostic.Kind.ERROR,
    "@GenerateBuilder requires at least one field",
    element
);

다중 라운드 처리

애너테이션 처리는 여러 라운드에 걸쳐 진행됩니다. 애너테이션이 포함된 파일을 생성하면 다음 라운드에서 프로세서가 다시 실행될 수 있습니다. roundEnv.processingOver()는 마지막 라운드임을 나타냅니다.

if (roundEnv.processingOver()) {
    // last round — write summary files or do cleanup
}

Lombok 내부 동작

Lombok은 기존 클래스의 AST를 수정하는 비표준 APT 확장을 사용합니다(명세상 허용되지 않음). @Data, @Builder, @Getter와 같은 애너테이션은 메서드를 컴파일된 클래스에 직접 생성합니다.

MapStruct 코드 생성

MapStruct는 컴파일 시점에 유형 안전 매퍼 구현체를 생성합니다. @Mapper가 지정된 인터페이스를 읽고 구현체를 일반 Java 클래스로 작성하므로 런타임에 리플렉션이 전혀 필요하지 않습니다.

@Mapper
public interface UserMapper {
    UserDto toDto(User user);
    User toEntity(UserDto dto);
}
// MapStruct generates: UserMapperImpl.java at compile time

애너테이션 프로세서 테스트하기

google/compile-testing 또는 Kotlin용 Kapt를 사용하여 프로세서를 단위 테스트합니다. 소스 문자열을 입력하고 생성된 파일 또는 컴파일러 오류를 확인합니다.

JavaFileObject src = JavaFileObjects.forSourceString("Test",
    "@GenerateBuilder public class Test { private String name; }");
Compilation c = Compiler.javac().withProcessors(new BuilderProcessor()).compile(src);
CompilationSubject.assertThat(c).succeeded();
CompilationSubject.assertThat(c).generatedSourceFile("TestBuilder");

프로세서 패키징

프로세서를 별도의 Maven 모듈로 패키징합니다. 애너테이션 모듈(애너테이션만 포함)은 compile 의존성이고, 프로세서 모듈은 annotationProcessor 범위이며 런타임 의존성으로 사용하지 않습니다.

// build.gradle:
dependencies {
    implementation "com.example:my-annotations:1.0"
    annotationProcessor "com.example:my-processor:1.0"
}

빠른 확인

자동 검색을 위해 애너테이션 프로세서를 어디에 등록하나요?

정리

AbstractProcessor를 확장하고 META-INF/services에 등록하며, Filer로 소스를 생성하고 Messager로 오류를 출력합니다. 프로세서는 별도로 패키징합니다. 단위 테스트에는 compile-testing을 사용합니다. 이렇게 하면 런타임의 리플렉션 오버헤드가 제거됩니다.

자주 묻는 질문

“컴파일 시점 주석 처리기” 강의는 무료인가요?

네 — “컴파일 시점 주석 처리기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Java Academy 강의 전체를 잠금 해제할 수 있습니다. Java Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“컴파일 시점 주석 처리기”에서 뭘 배우나요?

컴파일 시점에 소스 파일을 생성하거나 코드를 검증하는 AbstractProcessor를 작성합니다. 브라우저에서 직접 실행하는 실습 코드로 Java Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Java Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Java Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“컴파일 시점 주석 처리기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Java Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Java Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 주석 정의: 요소와 기본값
  2. 유지 정책과 대상 유형
  3. 런타임 주석 처리
  4. 컴파일 시점 주석 처리기
← Java Academy(으)로 돌아가기