@Component
public class OrderService {
private final MemberRepository memberRepository;
@Autowired
public OrderService (MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
스프링빈에서는 생성자가 1개만 있으면 @Autowired가 생랼되어도 자동으로 주입된다.
@Component
public class OrderService {
private MemberRepository memberRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Autowired는 주입할 대상이 없으면 오류가 발생하기에 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false) 로 지정하면 된다.
@Component
public class OrderService {
@Autowired
private MemberRepository memberRepository;
}
순수한 자바 테스트 코드에서는 @Autowired가 동작하지 않는다.
@Component
public class OrderService {
private final MemberRepository memberRepository;
@Autowired
public void init(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Component
public class OrderService {
private final MemberRepository memberRepository;
@Autowired
public OrderService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final 키워드를 사용할 수 없다. 오직 생성자 주입 방식만 final 키워드를 사용할 수 있다.
롬복에서 @RequiredArgsConstructor를 사용하면 컴파일 시점에 생성자 코드를 자동으로 생성해주기에 코드가 간결해진다.
@Component
@RequiredArgsConstructor를
public lcass OrderService {
private final MemberRepository memberReposiory;
}
@Autowired
private Coffee coffee;
@Component
public class IceAmericano implements Coffee {}
@Component
public class HotAmericano implements Coffee {}
이 경우 실행하면 NoUniqueBeanDefinitionException
에러가 발생한다. 따라서 이를 해결하디 위한 방식을 알아보자.
기존에 @Autowired 로 작성한 코드에서 명칭을 변경함
@Autowired
private Coffee coffee;
// 필드 명을 빈 이름으로 ㅇ변경
@Autowired
private Coffee iceAmericano;
@Qualifier
는 추가 구분자를 붙여주는 방식으로 주입 시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하는 것은 아니다.
@Component
@Qualifier("IceAmericano")
public class IceAmericano implements coffee {}
@Component
@Qualifier("HotAmericano")
public class HotAmericano implements coffee {}
@Qualifier를 사용하게 되면 빈 이름을 적어주어 생성자, 수정자를 자동으로 주입할 때 편하게 할 수 있다.
@Autowired
public OrderService (@Qualifier("HotAmericano") Coffee coffee) {
this.coffee = coffee;
}
@Autowired
public Coffee setCoffee(@Qualifier("HotAmericano") Coffee coffee) {
return coffee;
}
@Component
@Primary
public class IceAmericano implements coffee {}
@Component
public class HotAmericano implements coffee {}