티스토리 뷰
Annotation
Java 5부터 추가된 기능으로 소스 코드에 메타 데이터를 추가하는 것입니다. 클래스, 메소드, 변수 등에 붙여서 사용하게 됩니다.
애노테이션 정의하는 방법은 다음과 같습니다.
public @interface DoRepeat100 {}
Interface를 정의한 뒤 interface 키워드 앞에 @를 붙입니다. 위 애노테이션은 같은 작업을 100번 반복하는 것을 의미합니다.
위에서 생성한 애노테이션을 부여하여 메소드를 구현하였습니다.
public class Hello {
@DoRepeat100
public void hello() {
System.out.println("Helllo");
}
}
hello라는 메소드는 애노테이션을 부여받았습니다.
이제 이 애노테이션을 처리하는 클래스를 살펴보겠습니다.
public class Main {
public static void main(String[] args) {
Hello hello = new Hello();
try {
Method method = hello.getClass().getDeclaredMethod("hello");
if (method.isAnnotationPresent(DoRepeat100.class)) {
System.out.println("애노테이션이 존재합니다.");
for (int i = 0; i < 100; i++) {
hello.hello();
}
} else {
System.out.println("애노테이션이 존재하지 않습니다.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java의 reflection의 기술을 이용해 클래스의 메소드 정보를 추출한 뒤 해당 메소드에 애노테이션이 부여되어 있는지 여부에 따라 if 문으로 분기 처리를 하였습니다.
Annotation 옵션
✔️@Retention
해당 애노테이션이 언제까지 유효한지를 정해줄 수 있는 옵션입니다. SOURCE, CLASS, RUNTIME 값을 지정할 수 있고 기본값은 CLASS 입니다.
- SOURCE: 컴파일러(compiler)에 의해 사라지는 애노테이션으로 source 상에서만 확인이 가능하므로 거의 주석과 같다고 볼 수 있습니다.
- CLASS: 컴파일러에 의해 class 파일에는 저장이 되지만, JVM이 실행할 때는 유지될 필요가 없어 Runtime 시에는 확인할 수 없는 애노테이션입니다.
- RUNTIME: JVM에 의해 런타임 시에도 유효한 애노테이션입니다.
✔️@Target
애노테이션이 부여될 위치를 지정하는 옵션입니다.
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface DoRepeat100 {}
위 예제의 경우 런타임 시까지 유지가 되며, 메소드에만 부여할 수 있는 애노테이션으로 클래스나 변수 등에 부여하는 경우 컴파일 에러가 발생합니다.
✔️@Documented
javadoc으로 문서 생성 시 문서에도 애노테이션 정보가 표현되도록 하는 옵션입니다.
Built-in Annotation
✔️@Override
메소드가 오버라이딩 되었는지 검증하는 애노테이션입니다. 만약 부모 클래스 또는 구현해야할 인터페이스에서 해당 메소드를 찾을 수 없는 경우 컴파일 에러가 발생합니다.
✔️@Deprecated
메소드를 사용하지 않도록 유도하는 애노테이션으로 만약 해당 애노테이션이 부여된 메소드를 사용하게 되면 컴파일 에러가 발생합니다.
✔️@FuntionalInterface
람다 함수 등을 위한 인터페이스에 지정하는 애노테이션입니다. 메소드가 없거나 두개 이상인 경우 컴파일 에러가 발생합니다. (Java 8 이상)
애노테이션 프로세서
컴파일 타임에 애노테이션을 분석하여 붙여진 애노테이션을 프로세싱하는 javac에 속한 빌드 툴입니다. 특정 애노테이션을 위한 애노테이션 프로세서는 자바 코드 (또는 컴파일된 바이트 코드)를 input으로 받아서 output으로 파일(보통 .java 파일)을 생성합니다.
작동 순서는 다음과 같습니다.
1. 애노테이션 클래스를 생성합니다.
2. 애노테이션 파서(parser) 클래스를 생성합니다.
3. 애노테이션을 사용합니다.
4. 컴파일 시 애노테이션 파서가 애노테이션을 처리합니다.
5. 자동 생성된 클래스가 빌드 폴더에 추가됩니다.
Annotation Parser Classes는 컴파일 시에만 사용되며 빌드가 된 후에는 사용되지 않습니다.
모든 Annotation Processor는 AbstractProcessor를 상속받습니다.
package com.example;
public class MyProcessor extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment env){ }
@Override
public boolean process(Set<? extends TypeElement> annoations, RoundEnvironment env) { }
@Override
public Set<String> getSupportedAnnotationTypes() { }
@Override
public SourceVersion getSupportedSourceVersion() { }
}
- init(ProcessingEnvironment env)
: 모든 애노테이션 프로세서 클래스는 빈 생성자를 반드시 가져야 합니다. 대신, ProcessingEnvironment를 파라미터로 받아 애노테이션 프로세싱 툴이 호출하는 특별한 init() 메소드도 가지고 있습니다. ProcessingEnvironment는 Element, Type, Filter와 같이 유용한 유틸리티 클래스를 제공합니다.
- process(Set<? extends TypeElement> annoations, RoundEnvironment env)
: 각각의 프로세서의 main() 메소드 역할을 합니다. 여기에 scanning, evaluating, 애노테이션 프로세싱, 자바 파일 생성을 위한 코드를 작성합니다. RoundEnvironment 파라미터를 사용하여 특정 애노테이션이 부여된 요소를 찾을 수 있습니다.
- getSupportedAnnotationTypes()
: 해당 애노테이션 프로세서가 처리할 애노테이션을 명시합니다.
- getSupportedSourceVersion()
: 특정 자바 버전을 명시하는데 사용합니다. 보통 SourceVersion.latestSupported()를 리턴합니다.
작성한(컴파일된) 애노테이션 프로세서를 .jar 파일로 패키징합니다. 이때 META-INF/services에 위치하는 javax.annotation.processing.Processor라는 특정 파일도 같이 .jar 파일로 패키징합니다.
javax.annotation.processing.Processor 파일의 내용은 new line을 구분자로 사용하는 프로세서들의 full qualified class name의 목록입니다.
com.example.MyProcessor
com.foo.OtherProcessor
net.blabla.SpecialProcessor
javac이 위에서 생성한 .jar 파일을 이용해 자동으로 javax.annotation.processing.Processor 파일을 찾아 직접 생성한 애노테이션 프로세서를 등록합니다.
참고
- nesoy.github.io/articles/2018-04/Java-Annotation
- medium.com/@jason_kim/annotation-processing-101-%EB%B2%88%EC%97%AD-be333c7b913
'JAVA' 카테고리의 다른 글
[Java Study 14] 제네릭 (1) | 2021.05.15 |
---|---|
[Java Study 13] I/O (0) | 2021.05.13 |
[Java Study 11] Enum (0) | 2021.05.11 |
[Java Study 10] 멀티쓰레드 프로그래밍 (0) | 2021.05.07 |
[Java Study 08] 인터페이스 (0) | 2021.05.05 |
- Total
- Today
- Yesterday
- permutation
- 소수
- ECR
- CodeCommit
- BFS
- Dynamic Programming
- Baekjoon
- Algorithm
- DFS
- search
- EC2
- ionic
- java
- string
- cloudfront
- 프로그래머스
- array
- spring
- CodePipeline
- Combination
- SWIFT
- sort
- map
- 조합
- 수학
- programmers
- AWS
- 순열
- CodeDeploy
- 에라토스테네스의 체
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |