스프링 리플렉션과 의존성 주입

오영선·6일 전
0

javaSpring

목록 보기
7/7

스프링에서 리플렉션(Reflection)은 주로 런타임 시점에 동적으로 수행하기 위해 사용된다.

  • 클래스의 메타데이터에 접근하거나,
  • 메서드 호출,
  • 필드 수정 등을 동적으로 가능하게 유연한 생성과 조작이 가능하다.

리플렉션으로 얻을 수 있는 정보

  • 클래스의 메타 데이터 : 클래스 이름, 접근제어자, 부모클래스, 구현된 인터페이스 등
  • 필드 정보 (접근 및 수정)
  • 메서드 정보 (정보확인, 동적 호출)
  • 생성자 정보 : 생성자를 활용해 동적으로 객체 생성 가능

리플렉션의 사용처(in Spring)

  • DI(의존성 주입): 스프링이 빈을 주입할 때 클래스 타입이나 필드에 접근하여 인스턴스를 생성하고, 필요한 의존성을 주입합니다.
    *private final...필드, @Autowired 등등 해당
  • 애노테이션 기반 프로그래밍: @Autowired, @Transactional, @RequestMapping 등 애노테이션을 통해 메타데이터를 읽고 동작을 수행합니다.
  • AOP(Aspect-Oriented Programming): 리플렉션을 통해 메서드를 프록시로 감싸고, 전처리나 후처리 로직을 삽입하여 애스펙트를 적용합니다.

    예시 : 서블릿

중요한 것은 컴파일 시간에 모든 것을 결정하지 않는다 는 것이다.
"나는 이 객체에서 특정 서비스를 사용할거야" 정도의 계획만 세우고, 실제로 어떤 서비스를 주입할지는 '런타임'시점에 결정된다.

  • 스프링은 '런타임'에 내가 미리 정해놓은 위치에 맞는 의존성 객체를 찾아와 배치한다.

이러한 방식에서 우리는 장점과 단점을 함께 유추할 수 있다.
장점 : 유연하다. 개발자는 주입을 직접 신경쓰지 않기 때문에 비지니스 로직에 집중할 수 있게 된다.
단점 : 개발자가 신경쓰지 않는다는 것. 런타임에 주입된다는 것은 즉 컴파일 시점에는 오류를 발견하지 못할수도 있다는 뜻이 된다. 또, 스프링의 할일이 늘어나 무거워질 수 있다.

그렇다면 리플렉션은 의존성 주입을 실제로 어떻게 실행하고 있을까?

  1. autowire에 대한 메타정보 찾기
    findAutowiringMetadata() : 빈(Bean) 이름이나 클래스 이름을 키(key)로 사용해서 캐시에서 메타데이터를 조회한다.
  • 스프링은 리플렉션을 사용하여 클래스에 선언된 필드, 메서드, 생성자 등을 확인하고, @Autowired, @Value, @Inject와 같은 주입 관련 애노테이션이 붙어 있는지 확인합니다.
  1. 생성자 고르기
    beanClass.getDeclaredConstructors()를 호출하여 클래스에 선언된 모든 생성자를 가져온다.
  • 리플렉션을 통해 의존성을 주입해야 할 필드나 메서드를 찾은 후, 해당 필드나 메서드에 주입할 빈을 스프링 컨텍스트에서 검색합니다.
  1. 의존성 주입해주기
    이 메서드 내에서 InjectionMetadata.inject()를 호출할 때, 실제 의존성 주입을 수행하는 과정에서
  • 리플렉션을 이용해 필드에 직접 접근하여 값을 설정하거나, 메서드를 호출해 값을 주입합니다. 필드가 private로 선언되어 있어도 리플렉션을 통해 접근할 수 있습니다

자세한 정보는 아래 게시글에서 깊게 이해할 수 있었다.
https://curiousjinan.tistory.com/entry/spring-constructor-injection-reflection

0개의 댓글