앞에서 스프링 컨테이너가 @Autowired 애노테이션을 찾아서 스프링 빈을 자동으로 주입했습니다.
이렇게 의존관계를 주입하는것은 아래와 같이 다양한 방법이 있습니다.
- 생성자 주입
- 수정자 주입
- 필드 주입
- 일반 메서드 주입
- 롬복을 사용한 주입
생성자 주입
생성자 주입 방법은 지금까지 사용한 방법으로 생성자 호출시점에 딱 1번 호출됩니다.
package hello.core.order;
...
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
// TODO Auto-generated constructor stub
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
}
OrderServiceImpl (MemberRepository memberRepository, DiscountPolicy discountPolicy) 통해 주입합니다.
수정자 주입
필드의 값을 변경하는 setter 메서드를 통해서 의존관계를 주입하는 방법입니다.
package hello.core.order;
...
@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;
}
...
}
필드 주입
필드에 바로 주입하는 방법으로 간단하지만 외부에서 변경이 불가능하는 단점이 있습니다.
package hello.core.order;
...
@Component
public class OrderServiceImpl implements OrderService{
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
...
}
일반 메서드 주입
일반 메서드를 만들어서 주입을 받을 수 있으며, 한번에 여러 필드를 주입할 수 있습니다.
package hello.core.order;
...
@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;
}
...
}
롬복을 사용한 주입
롬복을 사용한 방법은 롬복 라이브러리가 제공하는 @RequiredArgsConstructor 기능을 사용한 방식입니다.
package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
...
}
@RequiredArgsConstructor 는 final 이 붙은 필드의 생성자를 자동으로 만들어줌
옵션
- @Autowired(required = false)
- @Nullable
- Optional<>
@Autowired 는 주입할 대상이 없으면 오류가 발생합니다.
주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false ) 로 옵션을 줘야 합니다.
package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
...
}
@Autowired 의 기본 옵션은 (required = true)
이 외에도 @Nullable 과 Optional<> 을 사용한 방법이 있습니다.
@Nullable 은 주입할 대상이 없으면 null 이 입력되며, Optionanl<> 은 Optional.empty 가 입력됩니다.
package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
@Autowired
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
...
}
'Spring > Spring 핵심 원리' 카테고리의 다른 글
컴포넌트 스캔 (0) | 2023.01.21 |
---|---|
스프링 컨테이너와 스프링 빈 (0) | 2023.01.20 |
예제 만들기 - AppConfig 생성 (0) | 2023.01.20 |
예제 만들기 - 주문과 할인 도메인 설계 (0) | 2023.01.20 |
객체 지향과 스프링 - 좋은 객체 지향 설계의 5가지 원칙 (0) | 2023.01.16 |