DI

강한친구·2022년 4월 11일
0

Spring

목록 보기
2/27

주입 방법

생성자 주입

@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회 호출되는것을 보장한다
따라서 불변하는 것들에 많이 사용된다.

수정자 주입 (setter)

@Component
public class OrderServiceImpl implements OrderService{
    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    @Autowired
    public void setMemberRepository(MemberRepository memberRepository) {
        System.out.println("memberRepository = " + memberRepository);
        this.memberRepository = memberRepository;
    }
    @Autowired
    public void setDiscountPolicy(DiscountPolicy discountPolicy) {
        System.out.println("discountPolicy = " + discountPolicy);
        this.discountPolicy = discountPolicy;
    }

특징
선택 변경 가능성이 있는필드에 사용 가능
주입동작이 없어서 Autowired를 작동하게 하려면
Autowired(required=false)로 설정한다

필드 주입

@Component
public class OrderServiceImpl implements OrderService{
    @AutoWired private MemberRepository memberRepository;
    @AutoWired private DiscountPolicy discountPolicy;

이런식으로 바로 집어넣는방식이다.
하지만 이는 권장되지 않는다. (안티패턴)

특징

코드가 간결하지만, 외부에서 변경이 불가능하다.
이런 경우 테스트 구성이 불편해진다.

일반 메서드 주입

일반 메서드를 통해 주입 받을 수 있다.
특징
한번에 여러필드 주입받을 수 있으나, 일반적으로 잘 사용하지 않는다.

자동 DI는 스프링 빈에서만 작동한다. 클라스같은데서는 아무리 @Autowired 해봤자 작동안한다.

옵션처리

주입할 빈이 없어도 동작해야 할 때는 Autowired값을 바꿔야한다.

Autowired만 쓰면 기본적으로 required 값이 true이다.

세 가지 방법

        @Autowired(required = false)
        public void setNoBean1(Member noBean1) {
            System.out.println("noBean1 = " + noBean1);
        }

        @Autowired
        public void setNoBean2(@Nullable Member noBean2) {
            System.out.println("noBean2 = " + noBean2);
        }

        @Autowired
        public void setNoBean3(Optional<Member> noBean3) {
            System.out.println("noBean3 = " + noBean3);
        }

required false를 쓰지 않으면, 주입할 빈이 없으면 오류가 난다.

Nullable을 쓰면 null일 경우 null 을 반환,
Optional을 쓰면 Optional.empty를 반환한다 .

생성자 주입을 쓰는 이유

불변

  • 대부분의 의존관계는 1회만 주입하고 변경할 일이 없고, 변해서도 안된다.

  • 수정자 주입을 쓰면, public을 써야하고, 이는 외부에 변경이 열려있다는 뜻이다.

  • 생성자를 써서 만들면, final을 써서 생성자로 값을 한번 넣고 다시는 안바꿀 수 있다.

lombok

롬복을 사용하면

@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

이렇게만 써도 알아서 final의 생성자를 만들어준다.

이렇게 하면 코드를 많이 줄일 수 있다.

0개의 댓글