스프링

스프링5 프로그래밍 입문 - 의존 자동 주입

담쏙 2023. 10. 2. 11:19
728x90

@Autowired

  • @Autowired 애노테이션을 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입
  • 자동 주입 대상이 필수가 아닌 경우에는 @Autowired(required=false) 로 지정
    • 빈이 존재하지 않을 때 자동 주입 대상이 되는 필드나 메서드에 null 을 전달하지 않음 (기본생성자에 있는 그대로 사용)
    • 일치하는 빈이 없으면 값 할당 자체를 하지 않음
  • 스프링5 부터는 의존 주입 대상에 Optional을 사용해도 됨
    • 매칭되는 빈이 없으면 값이 없는 Optional을 할당
    @Autowired
    public void setDateFormatter(Optional<DateTimeFormatter> formatterOpt) {
        if (formatterOpt.isPresent()) {
            this.dateTimeFormatter = formatterOpt.get();
        } else {
            this.dateTimeFormatter = null;
        }
    }
  • @Nullalbe 애노테이션을 사용해도 된다
    // 자동 주입할 빈이 존재하면 해당 빈을 전달하고, 아니면 null을 전달
    @Autowired
    public void setDateFormatter(@Nullable DateTimeFormatter datetimeFormatter) {
        this.dateTimeFormatter = datetimeFormatter;        
    }

 

@Qualifier

  • 자동 주입 가능한 빈이 두 개 이상일 때 자동 주입할 빈을 한정할 수 있음
    @Bean
    @Qualifier("printer")
    public MemberPrinter memberPrinter1() {
        return new MemberPrinter();
    }

    @Bean
    public MemberPrinter memberPrinter2() {
        return new MemberPrinter();
    }
@Autowired
    @Qualifier("printer")
    public void setPrinter(MemberPrinter printer) {
        this.printer = printer;
    }
  • 필드와 메서드에 모두 적용할 수 있음
  • 설정에 @Qualifier 애노테이션이 없으면 빈의 이름을 한정자로 지정
    @Bean
    public MemberPrinter printer() {
        return new MemberPrinter();
    }

    @Bean
    @Qualifier("mprinter")
    public MemberPrinter printer2() {
        return new MemberPrinter();
    }
  • printer() 메서드로 정의한 빈의 한정자는 빈의 이름인 “printer”가 됨
빈 이름 @Qaulifier 한정자
printer   printer
printer2 mprinter mprinter
infoPrinter   infoPrinter

 

상위/하위 타입 관계와 자동 주입

@Bean
    public MemberPrinter memberPrinter1() {
        return new MemberPrinter();
    }

    @Bean
    public MemberPrinter memberPrinter2() {
        return new MemberSummaryPrinter();
    }
  • bean 에러가 나는데, 이는 MemberSummaryPrinter가 MemberPrinter를 상속하고 있기 때문
  • MemberSummaryPrinter 는 MemberPrinter 에도 할당할 수 있으므로 어떤 빈을 주입해야할 지 알 수 없어 Exception 발생
  • @Qualifier를 사용하거나, Bean 리턴 타입 변경

 

자동 주입과 명시적 의존 주입 간의 관계

  • 설정 클래스에서 세터 메서드를 통해 의존을 주입해도 해당 세터 메서드에 @Autowired 애노테이션이 붙어 있으면 자동 주입을 통해 일치하는 빈을 주입
  • 의존 자동 주입과 수동 주입을 섞어 사용하고 있다면 일관되게 바꾸는 것이 나음