Spring DI(Dependency Injection)

1 minute read

의존 주입에서 ‘의존’

  • 한 클래스가 다른 클래스의 메서드를 실행하는 것
  • 클래스 내부에서 직접 의존 객체를 생성하는 것이 유지보수 관점에서 문제점을 유발할 수 있다.

DI

  • 객체를 직접 생성하는 대신 의존 객체를 전달받는 방식 사용
    • e.g. 생성자를 통해 의존 객체를 전달받는다.
    • 변경에 대해 유연함을 제공할 수 있다.

Object Assembler

  • 객체를 생성하고 의존 객체를 주입해주는 클래스
  • 스프링이 DI를 지원하는 Assembler

DI 방식

  • 각 장단점에 맞게 적재적소에 사용하자.

생성자 방식

  • 객체를 생성해 바로 리턴하는 방식
  • 빈 객체를 생성하는 시점에 모든 의존 객체가 주입
  • 파라미터가 개수가 많아질 경우에, 의존 객체를 일일이 확인하기 위해 수고스러움이 생길 수 있다.

Setter method 방식

  • 빈 객체 생성 후, 세터를 활용해 값을 채운 후 리턴하는 방식
  • 세터 메서드 이름을 통해 어떤 의존 객체가 주입되는지 명확히 확인할 수 있다
  • 제대로 주입해주지 않을 경우, NullPointerException이 발생할 수 있다.

관련 Annotation

  • @Configuration
    • 스프링 설정 클래스로 사용하기 위한 애노테이션
    • 설정 클래스를 내부적으로 스프링 빈으로 등록한다.
    • AnnotationConfigApplicationContext 클래스를 이용해 스프링 컨테이너를 생성한 후 사용 가능
  • @Bean
    • 해당 애노테이션이 붙은 메서드에 대해 한 개의 객체만 생성한다. (싱글톤)
    • 이는 다른 메서드에서, @Bean이 붙은 메서드를 메서드명을 통해 명시적으로 호출한 경우에도 동일하게 동작한다.
      • 스프링은 내부적으로 설정 클래스를 상속한 새로운 설정 클래스를 만들어서 사용한다.
  • @Autowired
    • 스프링 설정 클래스의 필드에 @Autowired 애노테이션을 붙이면 해당 타입의 빈을 찾아서 필드에 자동으로 할당해준다.
  • @Import
    • 함께 사용할 설정 클래스를 지정
    • 스프링 컨테이너를 생성할 때, @Import에 넣어준 설정 클래스를 지정하지 않아도 함께 컨테이너를 초기화하게 된다.
    • 설정 클래스를 계층 형태로 구성함으로써, 스프링 컨테이너를 생성할 때 최상위 설정 클래스 한 개만 사용할 수 있다.
  • @Qualifier
    • 자동 주입 가능한 빈이 두 개 이상인 경우, 자동 주입할 빈을 지정할 수 있는 방법
  • @Component
    • 스프링이 직접 클래스를 검색해서 빈으로 등록할 수 있게 해준다.
    • 수동 등록한 같은 이름의 빈이 존재할 경우, 수동 등록한 빈을 우선한다.
  • @ComponentScan
    • 설정 클래스에 지정하면 @Component 애노테이션이 붙은 클래스를 스캔해 스프링 빈으로 등록한다.
    • basePackages 속성값을 통해 스캔 대상 패키지 목록을 지정할 수 있다
    • excludeFilters 속성값을 통해 스캔할 때 특정 대상을 자동 등록 대상에서 제외할 수 있다.
    • 다른 스캔 대상들
      • @Component, @Controller, @Service, @Repository, @Aspect, @Configuration

Categories:

Updated: