롬복 사용하기
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
롬복 동작 원리
논란
원래는 애노테이션이 붙어있는 클래스의 정보를 참조만 할 수 있고, 수정을 할 수는 없다
공개된 API가 아닌 컴파일러 내부 클래스를 사용하여 기존의 소스 코드를 조작한다
특히 이클립스의 경우엔 Java Agent를 사용하면 컴파일러 클래스까지 조작하여 사용한다
마찬가지로 공개된 API가 아니기떄문에 버전 호환성에 문제가 생길 수 있다
그럼에도 불구하고 엄청난 편리한 때문에 널리 쓰이고 있으며, 대안이 몇가지 있지만 롬복의 모든 기능과 편의성을 대체하지는 못한다
Processor 인터페이스
유틸리티
<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 {
...
}
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;
}
유틸리티
애노테이션 프로세서 사용 예
애노테이션 프로세서 장점