-
[Java] Annotation, Meta data๋?Android/Java 2021. 2. 19. 18:27๋ฐ์ํ
- ์ด ๊ธ์ "์๋ฐ ์จ๋ผ์ธ ์คํฐ๋"๋ฅผ ํตํด ๊ณต๋ถํ ๋ด์ฉ์ ์์ฑํ์์ต๋๋ค.
Annotation์ด๋?
Anntation์ JDK 1.5๋ถํฐ ๋์ ๋ ๊ฒ์ผ๋ก ์๋ฐ ์์ค ์ฝ๋์ ์ถ๊ฐํ์ฌ ์ฌ์ฉํ ์ ์๋ ๋ฉํ๋ฐ์ดํฐ์ ์ผ์ข ์ ๋๋ค.
๋๋ถ๋ถ์ด ๋ง์ด ๋ดค์ ๋งํ @Override, @Deprecated ๊ฐ Annotation ์๋ก Annotation์ ๊ตฌํ๋ ์ ๋ณด์ ๋ฐ๋ผ ์ฐ๊ฒฐ๋๋ ๋ฐฉํฅ์ด ๊ฒฐ์ ๋ฉ๋๋ค.
์ฆ, ์ ์ฒด์ ์ธ ์์ค์ฝ๋์ ๋ก์ง์ ๋ฐ๊พธ์ง ์์ง๋ง Annotation์ ํ๊ฒ์ ์ฐ๊ฒฐ ๋ฐฉ๋ฒ์ด๋ ์์ค์ฝ๋์ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. Annotation์ ๊ธฐ๋ฅ์ ์ ํ์ฉํ๋ค๋ฉด ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ณ๋์ ์์คํ ์ค์ ์ Annotation์๊ฒ ์์ํจ์ผ๋ก์จ ๊ฐ๋ฐ์๋ค์ ๋ก์ง ๊ตฌํ์๋ง ์ง์คํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ Annotation์ ํตํด AOP(Aspect Object Programming)์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์ฐธ์กฐ(https://www.nextree.co.kr/p5864/)
Annotation์ ํน์ง
์๋ฐ Annotation๋ ๋ฉํ๋ฐ์ดํฐ์ ์ผ์ข ์ผ๋ก ๋ฉํ๋ฐ์ดํฐ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ด ์ฒ๋ฆฌํด์ผ ํ ๋ฐ์ดํฐ๊ฐ ์๋๋ผ, ์ปดํ์ผ ํ์๊ณผ ๋ฐํ์์์ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ ์ปดํ์ผํ๊ณ ์ฒ๋ฆฌํ ๊ฒ์ธ์ง ์๋ ค์ฃผ๋ ์ ๋ณด์ ๋๋ค.
์ปดํ์ผ๋ฌ์๊ฒ ์ฝ๋ ๋ฌธ๋ฒ ์๋ฌ๋ฅผ ์ฒดํฌํ๋๋ก ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ค๊ฑฐ๋, ๋ฐํ์ ๋ ํน์ ๊ธฐ๋ฅ์ ์คํํ๋๋ก ์ ๋ณด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
Built-in Annotation
@Override : ์ค๋ฒ๋ผ์ด๋ฉ ๋ฉ์๋์์ ๋ํ๋ด๊ณ ์์๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ๋ฉ์๋์ ํ๋์ ๋์ฒดํ ์ ์์ต๋๋ค. ๋ง์ฝ ๋ถ๋ชจ ํด๋์ค ๋๋ ์ธํฐํ์ด์ค์์ ํด๋น ๋ฉ์๋๊ฐ ์๋ค๋ฉด ์ปดํ์ผ ์ค๋ฅ๋ฅผ ๋ฉ๋๋ค.
@SuppressWarnings : ๋ค์ ์ด๋ ธํ ์ด์ ์ด ์๋ ์ฝ๋์์๋ ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ๋๋ก ํฉ๋๋ค.
@Deprecated : ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ๋ฉ์๋๋ฅผ ๋ปํฉ๋๋ค. ๊ทธ๋๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ ์ปดํ์ผ ๊ฒฝ๋ก๋ฅผ ๋ฐ์์ํต๋๋ค.
@SafeVarargs : ๊ฐ๋ณ์ธ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ ๋ ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํฉ๋๋ค.
@FunctionalInterface : ๋ฉ์๋๊ฐ ํ๋๋ง ์กด์ฌํ๋ ์ธํฐํ์ด์ค๋ก ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋๋ค ํจ์๋ฅผ ์ํ ์ธํฐํ์ด์ค๋ฅผ ๋ํ๋ ๋๋ค. ๋ฉ์๋๊ฐ ํ๋๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ์ปดํ์ผ ์ค๋ฅ๊ฐ ๋ฉ๋๋ค.
@Native : ๋ค์ดํฐ๋ธ ์ฝ๋์์ ์ฐธ์กฐํ ์ ์๋ ์์๋ฅผ ๋ํ๋ ๋๋ค.
Meta Annotation
Annotation์ ์ง์ ์ปค์คํฐ๋ง์ด์ง์ ํ ์ ์๋๋ฐ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด์๋ Meta Annotation์ ์์์ผ ํฉ๋๋ค.
@Target
Annotaion์ ์ ์ฉ ๋ฒ์๋ Target์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค. ์ค์ง ๋ฉ์๋์์ ์ฌ์ฉ๋ ์๋ ์๊ณ ์์ฑ์ ๋ฐ ํ๋ ์ ์ธ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. Target annotation ์ข ๋ฅ๋ 8๊ฐ ์์ต๋๋ค.@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.CONSTRUCTOR, ElementType.METHOD}) public @interface SafeVarargs { }
@Retention
Retention annotation์ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋จ lifecycle์์ annotation์ด ์ ์ฉ๋๋ ์์น๋ฅผ ์ง์ ํฉ๋๋ค.
3๊ฐ์ง ์ ์ฑ ์ด ์กด์ฌํ๊ณ ๊ฐ ๊ตฌ์ฑ์ ๋ํ ์ดํด๊ฐ ํ์ํฉ๋๋ค.- RetentionPolicy.SOURCE : ์ปดํ์ผ ์ดํ ์ปดํ์ผ๋ฌ์ ์ํด ์ญ์ ๋ฉ๋๋ค.
- RetentionPolicy.CLASS : ์ปดํ์ผ๋ฌ์ ์ํด ํด๋์ค ํ์ผ์ ๊ธฐ๋ก๋์ง๋ง ๋ฐํ์๊น์ง ์ ์ง๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ฆฌํ๋ ์ ์ ์ด์ฉํ์ฌ ์ด๋ ธํ ์ด์ ์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
- RetentionPolicy.Runtime : ํด๋์ค ํ์ผ์๋ ์ด๋ ธํ ์ด์ ์ ๋ณด๊ฐ ๊ธฐ๋ก๋๊ณ ๋ฐํ์ ์์ ๋ฆฌํ๋ ์ ์ ์ด์ฉํด์ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
- ์ฐธ์กฐ(https://nesoy.github.io/articles/2018-04/Java-Annotation)
@Documented
๋ฌธ์์ ์ด๋ ธํ ์ด์ ์ ๋ณด๊ฐ ํ๊ธฐ๋ฉ๋๋ค.
@Inherited
์์ ํด๋์ค๊ฐ ์ด๋ ธํ ์ด์ ์ ์์๋ฐ๋๋ก ํฉ๋๋ค.
@Repeatable
java8๋ถํฐ ์ง์ํ๋ฉฐ, ๋์ผํ ์ ์ธ์ annotation์ ๋๋ฒ ์ด์ ์ ์ฉํ ์ ์๋๋ก ํฉ๋๋ค.@Inherited // ์์ @Documented // ๋ฌธ์ํ @Retention(RetentionPolicy.RUNTIME) // ๋ฐํ์๊น์ง ์ ์ง @Target({ ElementType.PACKAGE, // ํจํค์ง ์ ์ธ ์ ElementType.TYPE, // ํ์ ์ ์ธ ์ ElementType.CONSTRUCTOR, // ์์ฑ์ ์ ์ธ ์ ElementType.FIELD, // ํด๋์ค ๋ฉค๋ฒ๋ณ์ ์ ์ธ ์ ElementType.METHOD, // ๋ฉ์๋ ์ ์ธ ์ ElementType.ANNOTATION_TYPE, // ์ด๋ ธํ ์ด์ ํ์ ์ ์ธ ์ ElementType.LOCAL_VARIABLE, // ์ง์ญ๋ณ์ ์ ์ธ ์ ElementType.PARAMETER, // ๋งค๊ฐ๋ณ์ ์ ์ธ ์ ElementType.TYPE_PARAMETER, // ๋งค๊ฐ๋ณ์ ํ์ ์ ์ธ ์ ElementType.TYPE_USE // ํ์ ์ฌ์ฉ ์ }) public @interface TodayAnnotation { public enum DAY{ MON, TUE, WED,TUR,FRI,SAT,SUN } String today() default "SUN"; int count() default 7; DAY getday() default DAY.SUN; }
Custom Annotation
@Inherited // ์์ @Documented // ๋ฌธ์ํ @Retention(RetentionPolicy.RUNTIME) // ๋ฐํ์๊น์ง ์ ์ง @Target({ ElementType.FIELD // ๋ฉ์๋ ์ ์ธ ์ }) public @interface TodayAnnotation { public enum DAY{ MON, TUE, WED,TUR,FRI,SAT,SUN } String today() default "SUN"; int count() default 7; DAY getday() default DAY.SUN; }
๋ค์๊ณผ ๊ฐ์ด Meta Annotation์ ์ ์ํ์์ต๋๋ค. ํ์ฌ ๋ฉํ ์ด๋ ธํ ์ด์ ์ ํด๋์ค ํ์ผ๊ณผ ๋๋ถ์ด ๋ฐํ์๊น์ง ์ ์ง๋๋ฉฐ, ๋ฉ์๋ ์ ์ธ ์์๋ง ์ด๋ ธํ ์ด์ ์ด ์ ์ฉ๋ฉ๋๋ค.
public class AnnoExample { @TodayAnnotation(today = "MON") private String strToday; @TodayAnnotation(count = 6) private int count; @TodayAnnotation(getday = TodayAnnotation.DAY.FRI) private Enum enumToday; void printAnnotation(){ System.out.println("TodayAnnotation"); } public String getStrToday() { return strToday; } public int getCount() { return count; } public Enum getEnumToday() { return enumToday; } }
์ด๋ ธํ ์ด์ ์ Target์ ๋ง๊ฒ ์ง์ ํ์๋ฉด ๋ฉ๋๋ค. Annotation Target์ Field๋ก ์ ์ํ๊ธฐ ๋๋ฌธ์ ๋ฉค๋ฒ ๋ณ์์๋ง ์ด๋ ธํ ์ด์ ์ด ์ง์ ๋๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
public class InvokeAnnotation { public InvokeAnnotation() { } private <T> T invokeAnnotation(T instance) throws IllegalAccessException{ Field[] fields = instance.getClass().getDeclaredFields(); for(Field field : fields){ TodayAnnotation anno = field.getAnnotation(TodayAnnotation.class); if(anno != null){ System.out.println(anno.today()); System.out.println(anno.count()); System.out.println(anno.getday()); } System.out.println(); } return instance; } public <T> T get(Class clazz) throws IllegalAccessException, InstantiationException{ T instance = (T) clazz.newInstance(); instance = invokeAnnotation(instance); return instance; } }
public class Main { public static void main(String[] args) throws InstantiationException,IllegalAccessException{ InvokeAnnotation demo = new InvokeAnnotation(); AnnoExample anno = demo.get(AnnoExample.class); anno.printAnnotation(); } }
์๋ฐ์์๋ ๋ฆฌํ๋ ์ ์ด๋ผ๋ ์ ์ฉํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ๋ฆฌํ๋ ์ ์ด๋ ๊ตฌ์ฒด์ ์ธ ํด๋์ค ํ์ ์ ์๊ธฐ ๋ชปํ๋๋ผ๋, ํด๋์ค์ ๋ฉ์๋, ํ์ , ๋ณ์๋ค์ ์ ๊ทผํ ์ ์๋๋ก ํด์ฃผ๋ ์๋ฐ API ์ ๋๋ค. ์์ ์๋ ์ฝ๋๋ Custom Annotation์ ์ฌ์ฉํ ํด๋์ค(AnnoExample)๋ฅผ ํธ์ถํ์ฌ ํ์ธํ๋ ํด๋์ค์ ๋๋ค. invokeAnnotation ๋ฉ์๋์์๋ ์ ๋๋ฆญ์ผ๋ก ์ฝ๋๊ฐ ๊ตฌํ๋์ด ์์ด ๊ตฌ์ฒด์ ์ธ ํด๋์ค ํ์ ์ ์์ง ๋ชปํ์ง๋ง ๋ฆฌํ๋ ์ ์ ์ด์ฉํ์ฌ ๋ฉค๋ฒ ๋ณ์๋ฅผ ํธ์ถํ๋ ๋ฉ์๋๋ฅผ ์คํํ์์ต๋๋ค.
์ฌ๊ธฐ์ Retentation์ผ๋ก ์ธํด ๊ฒฐ๊ณผ๊ฐ์ด ๋ฌ๋ผ์ง ์ ์์ต๋๋ค. TodayAnnotation์ ์ป๊ธฐ ์ํด getAnnotation ํจ์๋ฅผ ํธ์ถํ์์ต๋๋ค. ํ์ฌ TodayAnnotation์ Retentation์ RUNTIME์ผ๋ก ์ง์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ฆฌํ๋ ์ ์ ์ด์ฉํ์ฌ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค. ํ์ง๋ง ๊ทธ ๋ฐ์ CLASS, SOURCE๋ก ์ง์ ์ ๋ฐํ์ ์์๋ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์ต๋๋ค.
Annotation Processor
Annotation Process๋ ์๋ฐ ์ปดํ์ผ๋ฌ ํ๋ฌ๊ทธ์ธ์ ์ผ์ข ์ผ๋ก, ์ด๋ ธํ ์ด์ ์ ๋ํ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๊ฒ์ฌ, ์์ , ์์ฑํ๋ ์ญํ ์ ํฉ๋๋ค.
์ด๋ ธํ ์ด์ ์ฒ๋ฆฌ ๋์์ ์ฌ๋ฌ ๊ณผ์ ์ ๊ฑฐ์ณ์ ์ํ๋ฉ๋.์๋ฐ ์ปดํ์ผ๋ฌ๋ ์ด๋ ธํ ์ด์ ํ๋ก์ธ์์ ๋ํด ์๊ณ ์๋ ์ํ์์ ์ปดํ์ผ์ ์ํํฉ๋๋ค.
์คํ๋์ง ์์ ์ด๋ ธํ ์ด์ ํ๋ก์ธ์๋ค์ ์ํํฉ๋๋ค.
ํ๋ก์ธ์ ๋ด๋ถ์์ ์ด๋ ธํ ์ด์ ์ ๋ถ์ธ ํด๋์ค, ๋ฉ์๋, ๋ฉค๋ฒ๋ณ์๋ค์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํฉ๋๋ค.
์ปดํ์ผ๋ฌ๊ฐ ๋ชจ๋ ์ด๋ ธํ ์ด์ ํ๋ก์ธ์ค๊ฐ ์คํ๋์๋์ง ํ์ธํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ๋ฐ๋ณตํด์ ์์ ์ ์ํํฉ๋๋ค.
์ฐธ์กฐ (https://www.charlezz.com/?p=1167, https://mysend12.medium.com/java-annotation-processor-1-7f95693748ef)
๋ฐ์ํ'Android > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] Java Generic(์ ๋ค๋ฆญ) (0) 2021.03.01 [Java] Java IO, NIO (0) 2021.02.22 [Java] Enum์ด๋? (0) 2021.02.14 [Java] ์๋ฐ ์ฐ๋ ๋ ๊ต์ฐฉ์ํ(deadlock) (2) 2021.02.07 [Java] ์๋ฐ ์ฐ๋ ๋ ์ํ, ์ฐ์ ์์(State, Priority) (0) 2021.02.05