[Spring] @Autowired를 이용한 의존 자동 주입

Date:     Last Updated:

@Autowired

  • 이 어노테이션을 사용하면 스프링 컨테이너가 Bean으로 등록한 객체를 자동으로 주입해준다.
  • 이때 일치하는 Bean이 꼭 존재해야 자동주입이 가능하고 없다면 기본적으로는 예외가 발생한다.
  • 또한 같은 타입의 Bean이 두개일때도 예외가 발생한다. **

    @Qualifier

  • 자동 주입 가능한 빈이 두개 이상이면 @Qualifier(“mprinter”) 처럼 직접 지정해줘야한다.
  • 사용방법은 @Bean어노테이션으로 등록한 곳과 @Autowired으로 자동주입을 등록한 곳에서 사용 가능하다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  @Autowired
	@Qualifier("printer")
	public void setPrinter(MemberPrinter printer) {
		this.printer = printer;
	}

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

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

@Qualifier 이 없으면 빈의 이름을 한정자로 지정한다.

  • 아래 코드에서 printer() 메서드의 빈 이름 한정자는 printer이고
  • printer2() 메서드의 빈 이름 한정자는 printer2가 아닌 “mprinter”이다.
1
2
3
4
5
6
7
8
9
10
@Bean
public MemberPrinter printer(){
  return new MemberPrinter();
}

@Bean
@Qualifier("mprinter")
public MemberPrinter printer2(){
  return new MemberPrinter();
}

상속관계에서의 자동주입

  • MemberSummaryPrinter는 MemberPrinter를 상속받은 클래스이다.
  • 아래 코드는 정상적으로 실행될 것 같지만 에러가 난다. 스프링 컨테이너는 두 Bean 모두 MemberPrinter로 할당할 수 있기 때문이다.
  • 해결방법은 @Qualifier 로 이름 한정자를 지정해주거나 @Autowired를 해주는 부분에서 명시적으로 MemberSummaryPrinter로 의존주입을 받게 해주면 된다.
1
2
3
4
5
6
7
8
9
@Bean
public MemberPrinter printer(){
  return new MemberPrinter();
}

@Bean
public MemberSummaryPrinter printer2(){
  return new MemberSummaryPrinter();
}

@Autowired 어노테이션의 필수 여부

  • 말 그대로 자동 주입이기 때문에 @Autowired 어노테이션을 사용하기 위해서는 스프링 컨테이너에 Bean으로 등록이 되어있어야 한다.
  • 만약 @Autowired로 주입할 Bean이 등록되어있지 않다면 예외가 발생하게 된다.
  • 다만 Bean으로 등록되어있지 않아도 예외가 나지 않도록 하는 방법이 3가지 존재한다.

    1. @Autowired(required = false)

  • 이때 Bean이 등록되어있지 않다면 스프링컨테이너는 자동주입 자체를 실행하지 않는다.

    2. Optional

  • Bean이 존재하지 않으면 값이 없는 Optional 전달해줌으로써 예외를 발생시키지 않는다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    @Autowired
    public void setDateFormatter(Optional<DateTimeFormatter> formatterOpt){
    if(formatterOpt.isPresent()){
      this.dateTimeFormatter = formatterOpt.get();
    }
    else{
      this.dateTimeFormatter = null;
    }
    }
    

    3. @Nullable

  • @Nullable 어노테이션을 의존주입 파라미터 대상에 붙이면 Bean이 존재하지 않으면 null 을 전달한다.
  • @Autowired(required = false)는 값 자체를 할당하지 않지만, @Nullable은 Bean이 없으면 null을 반드시 할당한다.
1
2
3
4
@Autowired
public void setDateFormatter(@Nullable DateTimeFormatter dateTimeFormatter){
  this.dateTimeFormatter = dateTimeFormatter;
}

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

  • 예를 들어 @Autowired로 setter의존주입을 설정해놓은 상태에서 명시적으로 setter를 호출해서 주입을 하면 어떻게 될까?
  • 이때 스프링 컨테이너는 @Autowired로 설정한 자동주입을 우선시한다.
  • 그리고 @Autowired을 사용했다면 예외적인 상황을 제외하고 @Autowired를 사용해서 통일성을 유지하는 것이 좋다.

Leave a comment