Java의 Annotation 활용 및 커스텀 애너테이션 만들기

Java의 애너테이션(Annotation)은 메타데이터를 코드에 추가하는 방법으로, 코드에 대한 부가 정보를 제공하거나 특정 동작을 수행하도록 지시할 수 있습니다. 애너테이션은 프레임워크와 라이브러리에서 널리 사용되며, 커스텀 애너테이션을 통해 애플리케이션의 요구사항에 맞는 기능을 확장할 수 있습니다.

이번 글에서는 Java의 애너테이션 활용법과 커스텀 애너테이션 제작 방법을 알아보겠습니다.


1. Java 애너테이션의 기본 이해

**애너테이션(Annotation)**은 클래스, 메서드, 필드, 변수 등에 추가하여 컴파일러 또는 런타임 환경에서 특정 동작을 정의하거나 메타데이터를 제공하는 역할을 합니다.

대표적인 내장 애너테이션:

  1. @Override: 메서드가 부모 클래스의 메서드를 오버라이드했음을 명시 하고 있습니다.
  2. @Deprecated: 해당 요소가 더 이상 사용되지 않음을 나타내고 있습니다.
  3. @SuppressWarnings: 컴파일러 경고를 억제합니다.

사용 예:

public class AnnotationExample {
    @Override
    public String toString() {
        return "Annotation Example";
    }

    @Deprecated
    public void oldMethod() {
        System.out.println("This method is deprecated.");
    }
}

2. 애너테이션 활용 사례

  1. 의존성 주입:
    • Spring Framework의 @Autowired를 사용하여 객체를 주입합니다.
    @Autowired
    private UserService userService;
  2. RESTful API 설계:
    • @GetMapping, @PostMapping 등 Spring 애너테이션으로 HTTP 메서드 매핑을 정의합니다.
    @RestController
    public class UserController {
        @GetMapping("/users")
        public List<User> getAllUsers() {
            return userService.getAllUsers();
        }
    }
  3. 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;
    }

3. 커스텀 애너테이션 만들기

커스텀 애너테이션을 통해 애플리케이션의 특정 요구사항에 맞는 기능을 구현할 수 있습니다.

커스텀 애너테이션 제작 단계:

  1. 애너테이션 정의:
    • @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: 필드에만 적용됩니다.
  2. 애너테이션 처리:
    • 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");
                }
            }
        }
    }
  3. 애너테이션 적용:
    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. 커스텀 애너테이션 활용 사례

  1. 로깅:
    • 특정 메서드의 실행 시간을 측정하여 로깅합니다.
  2. 데이터 검증:
    • 사용자 입력 값을 검증하는 애너테이션입니다.
    @NotNull
    @Size(min = 1, max = 100)
    private String name;
  3. 권한 관리:
    • 사용자 역할에 따른 접근 제어 구현합니다.
    @RoleRequired("ADMIN")
    public void deleteUser() {
        // 관리자만 실행 가능
    }

5. 커스텀 애너테이션 사용 시 주의사항

  1. 성과 비용:
    • Reflection 사용으로 인해 성능이 저하될 수 있으므로 필요한 경우에만 사용합니다.
  2. 명확한 설계:
    • 애너테이션의 용도와 적용 범위를 명확히 정의해야 합니다.
  3. 도구 통합:
    • Spring, Hibernate와 같은 프레임워크와 통합하여 활용성을 극대화합니다.

결론

Java의 애너테이션은 코드의 가독성과 유지보수성을 높이고, 애플리케이션의 동작을 확장할 수 있는 유용한 도구입니다. 커스텀 애너테이션을 통해 애플리케이션의 요구사항에 맞는 기능을 구현하면 개발 생산성을 크게 향상시킬 수 있습니다. Reflection과의 조합으로 더욱 강력한 애플리케이션을 설계해 보시길 바랍니다. 감사합니다

 

Leave a Comment