애노테이션 프로세서
롬복(Lombok)
- 표준적으로 작성해야 할 코드를 개발자 대신 생성해주는 라이브러리
- @Getter, @Setter, @Builder 등
롬복 사용하기
- 의존성 추가
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
- IntelliJ lombok 플러그인 설치
- IntelliJ Annotation Processing 옵션 활성화
롬복 동작 원리
- 컴파일 시점에 애노테이션 프로세서를 사용해 소스코드의 AST(Abstraction Syntax Tree)를 조작
논란
-
원래는 애노테이션이 붙어있는 클래스의 정보를 참조만 할 수 있고, 수정을 할 수는 없다
-
공개된 API가 아닌 컴파일러 내부 클래스를 사용하여 기존의 소스 코드를 조작한다
-
특히 이클립스의 경우엔 Java Agent를 사용하면 컴파일러 클래스까지 조작하여 사용한다
마찬가지로 공개된 API가 아니기떄문에 버전 호환성에 문제가 생길 수 있다
-
그럼에도 불구하고 엄청난 편리한 때문에 널리 쓰이고 있으며, 대안이 몇가지 있지만 롬복의 모든 기능과 편의성을 대체하지는 못한다
애노테이션 프로세서
Processor 인터페이스
- 여러 라운드에 걸쳐 소스 및 컴파일 된 코드를 처리할 수 있음
유틸리티
- AutoService: 서비스 프로바이더 레지스트리 생성기.
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc6</version>
</dependency>
@AutoService(Processor.class)
public class MagicMojaProcessor extends AbstractProcessor {
...
}
- 컴파일 시에 애노테이션 프로세서를 사용하여 META-INF/services/javax.annotation.processor.Processor 파일을 자동으로 생성해 줌
Filer 인터페이스
- 소스 코드, 클래스 코드 및 리소스를 생성할 수 있는 인터페이스
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Magic.class);
for (Element element : elements) {
Name elementName = element.getSimpleName();
if (element.getKind() != ElementKind.INTERFACE) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Magic annotation can not be used on " + elementName);
} else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Processing " + elementName);
}
TypeElement typeElement = (TypeElement)element;
ClassName className = ClassName.get(typeElement);
//메서드 생성
MethodSpec pullOut = MethodSpec.methodBuilder("pullOut")
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", "Rabbit!")
.build();
//클래스 생성
TypeSpec magicMoja = TypeSpec.classBuilder("MagicMoja")
.addModifiers(Modifier.PUBLIC)
.addSuperinterface(className)
.addMethod(pullOut)
.build();
//소스 파일 생성, 바이트 코드 생성
Filer filer = processingEnv.getFiler();
try {
JavaFile.builder(className.packageName(), magicMoja)
.build()
.writeTo(filer);
} catch (IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "FATAL ERROR: " + e);
}
}
return true;
}
유틸리티
- Javapoet: 소스 코드 생성 유틸리티
애노테이션 프로세서 정리
애노테이션 프로세서 사용 예
- 롬복
- AutoService: java.util.ServiceLoader용 파일 생성 유틸리티
- @Override
- Dangger 2: 컴파일 타임 DI 제공
- 안드로이드 라이브러리
- ButterKnife: @BindView(뷰 아이디와 애노테이션 붙인 필드 바인딩)
- DeepLinkDispatch: 특정 URI 링크를 Activity로 연결할 때 사용
애노테이션 프로세서 장점
- 런타임 비용이 없음(컴파일 타임에 조작이 완료된 상황이기때문에)
참고
https://www.inflearn.com/course/the-java-code-manipulation
Author And Source
이 문제에 관하여(애노테이션 프로세서), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@alwayslee_12/애노테이션-프로세서저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)