스프링은 @Autowired 어노테이션을 이용한 다양한 의존성 주입(DI; Dependency Injection) 방법을 제공한다. 다시말하면 @Autowired는 Spring에게 의존성을 주입하는 지시자 역할로 쓰인다.
의존성 주입은 필요한 객체를 직접 생성하지 않고 외부에서 객체를 받아 사용하는 것이다. -> 코드의 재활용 ⬆️
생성자에 @Autowired 애너테이션을 붙여주면 스프링컨테이너에 등록된 Bean이 생성자에 필요한 빈(객체)들을 주입해준다.
@Component
public class CoffeeService {
private final MemberRepository memberRepository;
private final CoffeeRepository coffeeRepository;
@Autowired
public CoffeeService(MemberRepository memberRepository, CoffeeRepository coffeeRepository) {
this.memberRepository = memberRepository;
this.coffeeRepository = coffeeRepository;
}
}
- 의존관계 설정이 되지 않으면 객체생성이 불가능하다. 따라서,
👉🏻 컴파일 타임에 인지가 가능하다.
👉🏻 NPE(Null Point Exception)에러 방지가 가능하다.
의존관계 주입은 애플리케이션이 실행~종료 전까지 변경되어져선 안된다. 수정자 주입 같은 경우 메서드를 public으로 열어두었기 때문에 변경이 가능하여 적합하지 않다.
왜냐하면 누군가 실수로 변경할 수 있는 가능성도 있고 애초에 변경되면 안되는 메서드가 변경되는 것은 좋은 설계방법이 아니다.
- 의존성 주입이 필요한 필드를 final로 선언이 가능하다.
생성자 주입을 사용하면 필드에 final 키워드를 사용 할 수 있다. 생성자 주입을 제외한 나머지 주입방식은 생성자 이후 호출되는 형태이기 때문에 final키워드를 사용할 수 없다. 또한 생성자에서 값이 설정되지 않으면 컴파일 시점에서 오류를 확인할 수 있다.
// 오류
java: variable (데이터 이름) might not have been initialized
호출했을 때는 NPE(Null Point Exception)이 발생하는데 의존관계 주입이 누락되었기 때문에 발생한다.
생성자 주입을 사용하면 주입 데이터 누락 시 컴파일 오류가 발생한다.
- 스프링에서 순환참조감지가 가능하다.
👉🏻 순환 참조 시 앱구동이 실패하게 된다.
- 테스트 코드 작성이 용이하다.
- 수정자 주입이 필요한 경우가 있을 수 있지만 옵션이 필요할 때만 선택하면 된다.
setter라 불리는 필드 값을 변경하는 setter()메서드를 통해 의존관계를 주입하는 방법이다.
@Component
public class CoffeeService {
private MemberRepository memberRepository;
private CoffeeRepository coffeeRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setCoffeeRepository(CoffeeRepository coffeeRepository) {
this.coffeeRepository = coffeeRepository;
}
}
set+필드이름의 메서드를 생성하여 의존관계를 주입하는 것이 생성자 주입과의 차이점이다.
수정자메서드에는 @Autowired를 입력해야만 실행된다.
생성자가 1개일 때 @Autowired를 입력하지 않아도 작동이 되는 이유는,
스프링이 클래스(객체)를 빈에 등록할 때 생성자를 부를 수 밖에 없는데 그 때 의존관계주입도 같이 발생하게 되기 때문이다.
필드에 @Autowired 붙여서 바로 주입하는 방법이다.
@Component
public class CoffeeService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private CoffeeRepository coffeeRepository;
}
일반 메서드를 사용해 주입하는 방법이다.