카테고리 없음

[CS 발표] 어노테이션 Annotation

Rizingblare 2024. 4. 16. 02:17

1. 개요

어노테이션(Annotation)은 Java 5부터 새로 추가된 문법이다. 어노테이션을 직역하면 '주석'이라는 뜻이지만 자바에서는 @ 기호를 이용해 자바 코드에 특수한 의미를 부여하는 것을 의미한다. 주석은 사람에게 정보를 제공하지만 어노테이션은 특정 코드를 사용하는 프로그램에게 추가 정보를 전달하는 것이다.

 

위키백과에서는 다음과 같이 말하고 있다.

 

🌐 자바 애너테이션(Java Annotation)
자바 애너테이션(Java Annotation)은 자바 소스 코드에 추가하여 사용할 수 있는 메타데이터의 일종이다. 보통 @ 기호를 앞에 붙여서 사용한다. JDK 1.5 버전 이상에서 사용 가능하다. 자바 애너테이션은 클래스 파일에 임베디드되어 컴파일러에 의해 생성된 후 자바 가상머신에 포함되어 작동한다.

 

즉 프로그램에 추가적인 정보를 전달하는 메타데이터라고 볼 수 있다.

 

 

데코레이터 패턴

파이썬이나 JS, TS에 있는 데코레이터와 사용법과 기능이 매우 유사한데,

용법은 동일하지만 어노테이션은 컴파일러나 프레임워크, 혹은 라이브러리가 코드를 처리하기 위해 참조할 수 있는 추가 메타데이터를 제공하는 반면, 데코레이터 패턴을 적용한 언어들은 함수 또는 클래스의 동작을 직접 확장하거나 수정이 가능하기 때문에 더 유연하다는 점에서 차이가 있다.

 

 

2. 어노테이션의 종류

어노테이션은 주로 다음과 같은 역할을 수행한다.

 

어노테이션의 역할
·  컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공한다.

·  소프트웨어 개발 툴이 배치하거나 프로그램을 빌드할 때 코드를 자동으로 생성할 수 있도록 정보를 제공한다.
·  실행 시(런타임)에 특정 기능을 실행하도록 정보를 제공한다

 

이러한 어노테이션들은 크게 세 가지 종류로 구분되는데,

자바에서 기본적으로 제공하는 표준 어노테이션과 다른 어노테이션을 정의하는데 사용되는 메타 어노테이션, 마지막으로 사용자가 직접 정의하는 사용자 어노테이션이 있다.

 

다음과 같은 어노테이션들이 자바에서 제공하는 표준 어노테이션에 해당된다.

 

@Override: 오버라이딩을 올바르게 했는지 컴파일러가 체크한다.
@Deprecated: 앞으로 사용하지 않을 것을 권장하는 필드나 메서드에 붙인다.
@FunctionalInterface: 함수형 인터페이스에 붙이면, 컴파일러가 올바르게 작성했는지 체크
@SuppressWarnings: 컴파일러의 경고 메세지 대신 커스텀을 메시지를 발생

 

어노테이션들을 위한 어노테이션인 메타 어노테이션은 다음과 같다.


📌@Target : 어노테이션을 정의할 때, 적용대상을 지정하는데 사용한다.

@Target({TYPE, FIELD, TYPE_USE})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnnotation{}

@MyAnnotation // 적용 대상이 Type(클래스, 인터페이스)
class MyClass{
	@MyAnnotation //적용 대상이 FIELD인 경우
    int i;
    
    @MyAnnotation //적용 대상이 TYPE_USE인 경우
    MyClass mc;

📌@Retention : 어노테이션이 유지되는 기간을 지정하는데 사용한다

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override{}

📌@Inherited : 어노테이션도 상속이 가능하다. 어노테이션을 자손 클래스에 상속하고자 할 때, @Inherited를 붙인다.

@Inherited
@interface SuperAnno{}

@SuperAnno
class Parent{}

// <- 여기에 @SuperAnno 가 붙은 것으로 인식
class Child extends Parent{}

📌@Repeatable : 반복해서 붙일 수 있는 어노테이션을 정의할 때 사용

@Repeatable(ToDos.class)
@interface ToDo{
	String value();
}

@ToDo("delete test codes.")
@ToDo("override inherited methods")
class MyClass{
	~~
}

@interface ToDos{
	ToDo[] value();
}

@Repeatable 어노테이션은 위와 같이 "컨테이너 어노테이션"도 정의해주어야 한다.

 

📌@Documented : javadoc으로 작성한 문서에 포함시키려면 해당 어노테이션을 붙인다

 

 

3. 어노테이션의 생성

기본적으로 어노테이션을 사용하는 순서는 다음과 같다.

 

1. 어노테이션을 정의한다.
2. 클래스에 어노테이션을 배치한다.
3. 코드가 실행되는 중에 Reflection을 이용하여 추가 정보를 획득하여 기능을 실시한다.

 

자바 어노테이션은 다음과 같은 문법으로 생성할 수 있다.

@interface 이름{
	타입 요소 이름(); // 어노테이션의 요소를 선언
	    ...
}

 

위와 같은 문법으로 생성한 어노테이션의 몇 가지 예시들을 살펴보며 어노테이션 요소의 몇 가지 특징을 알아보자.

@interface DateTime{
	String yymmdd();
    String hhmmss();
}

@interface TestInfo{
	int count() default 1;
    String testedBy();
    TestType testType();
    DateTime testDate();
}


@TestInfo{
	testedBy="Kim",
    testTools={"JUnit", "AutoTester"},
    testType=TestType.FIRST,
    testDate=@DateTime(yymmdd="210922", hhmmss="211311")
)// count를 생략했으므로 default인 "count=1"이 적용된다.
public class NewClass{...}
  • 예시를 보면 알 수 있듯이 어노테이션 요소에는 값을 지정하지 않았을 때 사용될 기본값을 지정할 수 있다.
@interface TestInfo{
	String value();
}
@TestInfo("passed") // value="passed"와 동일
class NewClass{...}
  • 어노테이션의 요소가 하나뿐일때 요소 이름을 value로 지정하면 어노테이션을 적용할 때 요소의 이름을 생략할 수 있다.
@interface TestInfo{
	String[] testTools();
}

@TestInfo(testTools={"JUnit", "AutoTester"})
@TestInfo(testTools="JUnit") // 요소가 1개일 때는 {}를 사용하지 않아도 된다.
@TestInfo(testTool={}) // 요소가 없으면 {}를 써넣어야 한다.
  • 요소의 타입이 배열인 경우, 괄호 {}를 사용해서 할당한다.
@interface AnnoConfigTest{
    int id = 100; // 상수 ok
    String major(int i, int j) //매개변수 x
    String minor() throws Exception; // 예외 x
    ArrayList<T> list(); // 요소의 타입을 매개변수 x
  • 요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용된다.
  • 괄호()안에 매개변수를 선언할 수 없다.
  • 예외를 선언할 수 없다.
  • 요소의 타입을 매개변수로 정의할 수 없다.(<T>)
public interface Annotation{
	boolean equals(Object obj);
    int hashCode();
    String toString();
    
    Class<? extends Annotation> annotationType();
}
  • Annotation은 모든 어노테이션의 조상이며 상속은 불가능하다.

 

4. Spring 어노테이션

마지막으로 스프링에서 사용되는 어노테이션들을 살펴보자. 

〽️ @SpringBootApplication

SpringBoot를 자동으로 실행시켜주는 어노테이션으로 @Configuration, @EnableAutoConfiguration, @ComponentScan 3가지를 하나의 애노테이션으로 합친 것이다.
Bean 등록은 두 단계로 진행된다.
1) @ComponentScan을 통해 Component들을 Bean으로 등록한다.
2) @EnableAutoConfiguration을 통해 미리 정의해둔 자바 설정 파일들을 Bean으로 등록한다.


〽️ @Configuration

@Configuration을 클래스에 적용하고 @Bean을 해당 Class의 method에 적용하면 @Autowired로 Bean을 부를 수 있다. 1개 이상의 bean을 등록할 때 설정한다.


〽️ @ComponentScan
@Component와 @Service, @Repository, @Controller, @Configuration이 붙은 클래스 Bean들을 찾아서 Context에 bean등록을 해주는 Annotation이다.

Spring에서 @Component로 다 쓰지 않고 @Repository, @Service, @Controller등을 사용하는 이유는, 예를 들어 @Repository는 DAO의 메소드에서 발생할 수 있는 unchecked exception들을 스프링의 DataAccessException으로 처리할 수 있기 때문이다. 또한 가독성에서도 해당 애노테이션을 갖는 클래스가 무엇을 하는지 단 번에 알 수 있다.


〽️ @EnableAutoConfiguration
Spring Application Context를 만들 때 자동으로 설정하는 기능을 켠다. classpath의 내용에 기반해서 자동으로 생성해준다. 만약 tomcat-embed-core.jar가 존재하면 톰캣 서버가 setting된다.


〽️ @Component
@Component 은 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 Annotation이다. 1개의 class 단위로 bean으로 등록할 때 설정한다. @ComponentScan 선언에 의해 특정 패키지 안의 클래스들을 자동 스캔하여 @Component 어노테이션이 있는 클래스들에 대하여 Bean 인스턴스를 생성한다.


〽️ @Bean
@Bean은 개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean으로 만들려할 때 사용되는 Annotation이다. 1개의 외부 라이브러리로 부터 생성한 객체를 등록 시 사용 (new로 객체를 생성 후 직접 bean으로 등록할 때 사용)

ArrayList같은 라이브러리등을 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 Method를 만들고 @Bean Annotation을 사용하면 된다. Configuration 클래스에서 외부라이브러리 관련 객체를 미리 객체화 시켜놓을 때 많이 사용한다.


〽️ @Autowired
속성(field), setter method, constructor(생성자)에서 사용하며 Type에 따라 알아서 Bean을 주입해준다.
무조건적인 객체에 대한 의존성을 주입시킨다.이 Annotation을 사용할 시, 스프링이 자동적으로 값을 할당한다. Controller 클래스에서 DAO나 Service에 관한 객체들을 주입 시킬 때 많이 사용한다. 즉, Dependency Injection를 위한 곳에 사용된다.

 

 

# 참고문헌

https://sddev.tistory.com/225

 

[Spring Boot] 어노테이션 정리

SpringBoot란? Spring에서는 이러한 설정들을 자동화해주는 SpringBoot라는 프로젝트를 만들었다. Spring에서 SpringBoot라는 프레임워크를 내놓기 시작하면서 SpringBoot의 AutoConfigure(자동 구성) 기능을 통해

sddev.tistory.com

https://velog.io/@jkijki12/annotation

 

[Java] 어노테이션이 뭔데??

자바 어노테이션에 대해서 공부하자!!

velog.io

https://refactoring.guru/ko/design-patterns/decorator

 

데코레이터 패턴

/ 디자인 패턴들 / 구조 패턴 데코레이터 패턴 다음 이름으로도 불립니다: 래퍼(Wrapper), Decorator 의도 데코레이터는 객체들을 새로운 행동들을 포함한 특수 래퍼 객체들 내에 넣어서 위 행동들을

refactoring.guru

https://prinha.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98-annotation%EC%9D%98-%EC%A0%95%EC%9D%98%EC%99%80-%EC%A2%85%EB%A5%98

 

[Java / Spring ] 어노테이션(@, annotation)의 정의와 종류

(계속 추가중 / 최종수정일:20200831) 어노테이션(@, annotation)이란? Annotation은 Java5부터 새롭게 추가된 문법요소이다. 사전적으로는 "주석"이라는 의미를 가지고 있으며, 자바 코드에 @를 이용해 주석

prinha.tistory.com

https://velog.io/@rara_kim/Spring-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98Annotation

 

[Spring] 어노테이션(Annotation)

사전적 의미로는 주석이라는 뜻이지만, 자바에서 Annotaion(@)은 코드 사이에 특별한 의미, 기능을 수행하도록 하는 기술이다.프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공하고, 코

velog.io