쌓고 쌓다

의존관계 주입 방법 4가지 본문

프로그래밍/spring

의존관계 주입 방법 4가지

승민아 2023. 7. 14. 18:19

의존관계 주입 방법

  • 생성자 주입
  • 수정자 주입(setter 주입)
  • 필드 주입
  • 일반 메서드 주입

 

참고

1. 의존관계 자동 주입은 스프링 컨테이너가 관리하는 스프링 빈이어야 동작한다. (Member 같은 클래스는 동작하지 않음.)

2. @Autowired의 기본 동작은 주입할 대상이 없으면 오류가 발생한다. -> @Autowired(required=false)로 해결하자.

 

 

생성자 주입

@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;
    }
}

선택, 변경 의존관계에 사용

 

+ 자바빈 : 자바빈 관례에 따라 만들어진 클래스

자바빈 프로퍼티 규약에 필드의 값 수정, 조회는 getter, setter로만 한다는 규칙이 있다.

 

필드 주입

@Component
public class OrderServiceImpl implements OrderService {

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private DiscountPolicy discountPolicy;

}

권장하지 않는 방법이다.

테스트 코드 작성시에만 사용하자.

(순수 자바 테스트 코드에는 동작하지 않는다. @SpringBootTest처럼 스프링 컨테이너를 통합하여하는 경우에만 가능하다.)

 

일반 메서드 주입

@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) : 주입할 빈이 없으면 메서드 자체가 실행이 안된다.
  • @Nullable : 주입할 빈이 없으면 null이 입력된다.
  • Optional<> : 주입할 빈이 없으면 Optional.empty

=> 또한 생성자 주입에서 특정 필드에만 사용이 가능하다.

 

public class AutoWiredTest {

    @Test
    void AutowiredOption() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
    }

    static class TestBean {

        @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);
        }


    }
}

출력 결과

 

=> 생성자 주입 방식을 사용하자.

순수 자바 코드로 테스트를 돌릴 수 있고

이 방식만이 생성자 주입할 필드에 final 키워드로 값의 설정을 하지 않는 경우를 막을 수 있다.

옵션이 필요할 때 수정자 주입을 사용한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments