본문 바로가기
Everyday Study

2024.08.27(화) { 포인트컷 익스프레션, 정적&동적 매칭, @Qualifier, @CustomAnnotation }

by xogns93 2024. 8. 27.

정적매칭 - 메서드 오버로딩: 정적 매칭의 대표적인 예는 메서드 오버로딩입니다. 컴파일러는 동일한 이름의 메서드가 여러 개 존재할 때, 매개변수의 타입과 개수에 따라 호출할 메서드를 컴파일 시점에 결정합니다.

 

동적매칭 - 메서드 오버라이딩: 런타임 매칭의 대표적인 예는 메서드 오버라이딩입니다. 자바에서 다형성(polymorphism)을 이용해 부모 클래스의 참조 변수를 통해 자식 클래스의 메서드를 호출하는 경우, 실제 호출되는 메서드는 런타임에 결정됩니다.




@Qualifier : Spring Framework에서 주로 사용되는 애노테이션으로, 의존성 주입(Dependency Injection) 과정에서 같은 타입의 빈(Bean)이 여러 개 있을 때, 특정한 빈을 명시적으로 선택할 수 있게 해줍니다. Spring에서 @Autowired 애노테이션은 타입을 기준으로 빈을 자동으로 주입하지만, 동일한 타입의 빈이 여러 개 있을 경우 어느 빈을 주입해야 할지 혼란스러울 수 있습니다. 이때 @Qualifier를 사용하면 어느 빈을 주입할지 명확히 지정할 수 있습니다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

interface Vehicle {
    void drive();
}

@Component
class Car implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Driving a car");
    }
}

@Component
class Bike implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Riding a bike");
    }
}

@Component
class Traveler {

    private Vehicle vehicle;

    @Autowired
    public Traveler(@Qualifier("car") Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public void startJourney() {
        vehicle.drive();
    }
}

 


 

@CustomAnnotation : Java에서 사용자 정의 애노테이션(Custom Annotation)을 만드는 방법을 설명할 때 사용하는 일반적인 표현입니다. Java에서는 애노테이션을 사용하여 메타데이터를 정의할 수 있으며, 기본 제공 애노테이션 외에도, 필요에 따라 사용자 정의 애노테이션을 만들 수 있습니다. Java에서 애노테이션은 @interface 키워드를 사용하여 정의

 

기본적인 사용자 정의 애노테이션 예제

다음은 @CustomAnnotation이라는 간단한 애노테이션을 정의하고 사용하는 예제입니다.

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// @CustomAnnotation 정의
@Retention(RetentionPolicy.RUNTIME)  // 애노테이션의 유지 정책 설정
@Target(ElementType.METHOD)          // 애노테이션의 적용 대상 설정
public @interface CustomAnnotation {
    String value() default "default value";  // 기본값을 가지는 속성 정의
    int number() default 0;                  // 숫자 속성 정의
}

// 애노테이션을 사용하는 클래스
public class ExampleClass {

    @CustomAnnotation(value = "Custom Value", number = 10)
    public void annotatedMethod() {
        System.out.println("annotatedMethod가 호출되었습니다.");
    }

    public static void main(String[] args) throws Exception {
        ExampleClass example = new ExampleClass();
        example.annotatedMethod();

        // 리플렉션을 사용해 메서드에 정의된 애노테이션 정보를 출력
        CustomAnnotation annotation = example.getClass()
            .getMethod("annotatedMethod")
            .getAnnotation(CustomAnnotation.class);

        System.out.println("value: " + annotation.value());
        System.out.println("number: " + annotation.number());
    }
}

 


포인트컷 익스프레션(Pointcut Expression)

 

Spring AOP에서 포인트컷 익스프레션(Pointcut Expression)은 특정 조언(Advice)이 적용될 타겟을 정의하는 데 사용됩니다. 포인트컷 익스프레션은 Spring AOP에서 매우 중요한 개념으로, 어떤 메서드에 대해 조언이 적용될지 결정합니다. Spring AOP는 AspectJ의 포인트컷 표현식을 사용하는데, 이는 매우 강력하고 유연한 방식으로 메서드를 필터링할 수 있습니다.

 

 

모든 메서드에 적용

execution(* *(..))

 

특정 패키지 내의 모든 메서드에 적용

execution(* com.example.service.*.*(..))

 

특정 클래스의 메서드에만 적용

execution(* com.example.service.MyService.*(..))

 

특정 메서드 이름 패턴에 적용

execution(* com.example.service.MyService.get*(..))

 

특정 반환 타입을 가지는 메서드에 적용

execution(String com.example.service.MyService.*(..))

 

Pointcut 표현식을 사용하는 방법

포인트컷 표현식은 주로 @Aspect 애노테이션이 붙은 클래스에서 사용되며, @Before, @After, @Around 등의 어드바이스 애노테이션과 함께 사용됩니다.

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    // 포인트컷 표현식을 사용하여 특정 메서드에 Before Advice 적용
    @Before("execution(* com.example.service.MyService.*(..))")
    public void logBefore() {
        System.out.println("메서드 실행 전에 로그를 기록합니다.");
    }
}