Java의 애너테이션(Annotation)은 메타데이터를 코드에 추가하는 방법으로, 코드에 대한 부가 정보를 제공하거나 특정 동작을 수행하도록 지시할 수 있습니다. 애너테이션은 프레임워크와 라이브러리에서 널리 사용되며, 커스텀 애너테이션을 통해 애플리케이션의 요구사항에 맞는 기능을 확장할 수 있습니다.
이번 글에서는 Java의 애너테이션 활용법과 커스텀 애너테이션 제작 방법을 알아보겠습니다.
1. Java 애너테이션의 기본 이해
**애너테이션(Annotation)**은 클래스, 메서드, 필드, 변수 등에 추가하여 컴파일러 또는 런타임 환경에서 특정 동작을 정의하거나 메타데이터를 제공하는 역할을 합니다.
대표적인 내장 애너테이션:
@Override
: 메서드가 부모 클래스의 메서드를 오버라이드했음을 명시 하고 있습니다.@Deprecated
: 해당 요소가 더 이상 사용되지 않음을 나타내고 있습니다.@SuppressWarnings
: 컴파일러 경고를 억제합니다.
사용 예:
public class AnnotationExample {
@Override
public String toString() {
return "Annotation Example";
}
@Deprecated
public void oldMethod() {
System.out.println("This method is deprecated.");
}
}
2. 애너테이션 활용 사례
- 의존성 주입:
- Spring Framework의
@Autowired
를 사용하여 객체를 주입합니다.
@Autowired private UserService userService;
- Spring Framework의
- RESTful API 설계:
@GetMapping
,@PostMapping
등 Spring 애너테이션으로 HTTP 메서드 매핑을 정의합니다.
@RestController public class UserController { @GetMapping("/users") public List<User> getAllUsers() { return userService.getAllUsers(); } }
- ORM 매핑:
- Hibernate에서
@Entity
,@Table
,@Column
등의 애너테이션으로 객체와 데이터베이스를 매핑합니다.
@Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; }
- Hibernate에서
3. 커스텀 애너테이션 만들기
커스텀 애너테이션을 통해 애플리케이션의 특정 요구사항에 맞는 기능을 구현할 수 있습니다.
커스텀 애너테이션 제작 단계:
- 애너테이션 정의:
@interface
키워드를 사용하여 애너테이션을 정의합니다.
예:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface LogExecutionTime { }
설명:
@Retention
: 애너테이션이 유지되는 기간을 지정합니다.SOURCE
: 컴파일 시 제거 됩니다.CLASS
: 클래스 파일에 존재하지만 런타임에는 접근 불가합니다.RUNTIME
: 런타임에도 유지되어 Reflection으로 접근 가능합니다.
@Target
: 애너테이션이 적용될 수 있는 대상을 지정합니다.ElementType.METHOD
: 메서드에만 적용됩니다.ElementType.FIELD
: 필드에만 적용됩니다.
- 애너테이션 처리:
- Reflection을 사용하여 커스텀 애너테이션을 처리합니다.
예:
import java.lang.reflect.Method; public class AnnotationProcessor { public static void processAnnotations(Object obj) throws Exception { Class<?> clazz = obj.getClass(); for (Method method : clazz.getDeclaredMethods()) { if (method.isAnnotationPresent(LogExecutionTime.class)) { long start = System.currentTimeMillis(); method.invoke(obj); long end = System.currentTimeMillis(); System.out.println(method.getName() + " 실행 시간: " + (end - start) + "ms"); } } } }
- 애너테이션 적용:
public class Demo { @LogExecutionTime public void exampleMethod() { System.out.println("Executing method..."); } public static void main(String[] args) throws Exception { Demo demo = new Demo(); AnnotationProcessor.processAnnotations(demo); } }
출력:
Executing method... exampleMethod 실행 시간: 5ms
4. 커스텀 애너테이션 활용 사례
- 로깅:
- 특정 메서드의 실행 시간을 측정하여 로깅합니다.
- 데이터 검증:
- 사용자 입력 값을 검증하는 애너테이션입니다.
@NotNull @Size(min = 1, max = 100) private String name;
- 권한 관리:
- 사용자 역할에 따른 접근 제어 구현합니다.
@RoleRequired("ADMIN") public void deleteUser() { // 관리자만 실행 가능 }
5. 커스텀 애너테이션 사용 시 주의사항
- 성과 비용:
- Reflection 사용으로 인해 성능이 저하될 수 있으므로 필요한 경우에만 사용합니다.
- 명확한 설계:
- 애너테이션의 용도와 적용 범위를 명확히 정의해야 합니다.
- 도구 통합:
- Spring, Hibernate와 같은 프레임워크와 통합하여 활용성을 극대화합니다.
결론
Java의 애너테이션은 코드의 가독성과 유지보수성을 높이고, 애플리케이션의 동작을 확장할 수 있는 유용한 도구입니다. 커스텀 애너테이션을 통해 애플리케이션의 요구사항에 맞는 기능을 구현하면 개발 생산성을 크게 향상시킬 수 있습니다. Reflection과의 조합으로 더욱 강력한 애플리케이션을 설계해 보시길 바랍니다. 감사합니다