@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
생성자가 1개만 존재한다면
@Autowired
를 생략해도 자동 주입
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
참고:
@Autowired
의 기본 동작은 주입할 대상이 없으면 오류가 발생한다. 주입할 대상이 없어도 동작하게
하려면@Autowired(required = false)
로 지정하면 된다.
참고: 자바빈 프로퍼티 규약은 필드의 값을 직접 변경하지 않고 getter, setter 메소드를 이용하여 값을 읽거나 수정하는 규칙
@Configuration
같은 곳에서 사용@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
생성자 주입을 선택하자
- 생성자 주입 방식을 선택하는 이유는 여러가지가 있지만, 프레임워크에 의존하지 않고, 순수한 자바 언어의
특징을 잘 살리는 방법이기도 하다.- 기본으로 생성자 주입을 사용하고, 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다.
- 생성자 주입과 수정자 주입을 동시에 사용할 수 있다.
- 항상 생성자 주입을 선택해라! 그리고 가끔 옵션이 필요하면 수정자 주입을 선택해라. 필드 주입은 사용하지
않는게 좋다.
@Autowired(required=false)
: 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출 안됨//호출 안됨
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
org.springframework.lang.@Nullable
: 자동 주입할 대상이 없으면 null이 입력됨//null 호출
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
Optional<>
: 자동 주입할 대상이 없으면 Optional.empty 가 입력된다.//Optional.empty 호출
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
setNoBean2 = null
setNoBean3 = Optional.empty
@Autowired
는 타입(type)으로 조회ac.getBean(DiscountPolicy.class)
기존 코드
@Autowired
private DiscountPolicy discountPolicy
- 타입 매칭
- 타입 매칭의 결과가 2개 이상일 경우 필드 명, 파라미터 명으로 Bean 이름 매칭
@Autowired
private DiscountPolicy rateDiscountPolicy
@Qualifier
끼리 매칭- Bean 이름 매칭
NoSuchBeanDefinitionException
예외 발생
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Bean
을 이용한 직접 Bean 등록 시에도 사용할 수 있음@Qualifier
를 붙여주어야 함
@Autowired
시에 여러 개의 Bean이 매칭되면@Primary
가 우선권을 가짐
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
우선순위 :
@Qualifier
>@Primary