Skip to content

다양한 의존 관계 주입 방법 #30

@mingsound21

Description

@mingsound21

1. 생성자 주입

크게 4가지가 있다.

1. 생성자 주입
2. 수정자 주입(setter)
3. 필드 주입
4. 일반 메서드 주입

특징

  • 생성자 호출 시점에 딱 1번만 호출되는 것이 보장
  • “불변, 필수” 의존관계에 사용
    • 불변 : 생성자는 딱 1번만 호출됨

개발에서 불변은 중요하다.

⭐️생성자가 딱 1개인 경우, 생성자 위에 @Autowired 생략 가능.

생성자 주입은 빈을 등록할 때, 생성자를 사용해야하니까, 빈 생성 및 등록할 때, 의존관계 주입도 함께 발생한다.

→ 만약 생성자의 매개변수가 빈으로 등록되어있지 않다면, 해당 매개변수를 먼저 빈등록 할 것이다.

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

    //@Autowired // 생성자가 딱 1개라면, @Autowired 생략 가능. 어떤 생성자를 사용해야하는지 아니까.
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

2. 수정자 주입

  • setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법이다.

특징

  • 선택, 변경” 가능성이 있는 의존관계에 사용
    • memberRepository가 빈으로 등록되지 않았을 경우에도 해당 코드 사용이 가능하다.
    • 필수 의존관계가 아닌경우 @Autowired(required = false)설정
      • @Autowired의 기본 동작은 주입할 대상이 없다면, 오류 발생한다. 따라서 필수 의존관계가 아닌 선택 의존관계로 만들고 싶다면 required = false 설정을 반드시 해야 에러가 발생하지 않는다.
    • 혹은 중간에 내가 의존관계 빈 설정을 변경하고 싶은 경우에는 수정자 주입 사용
  • 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법이다.

스프링 컨테이너 생성과정에 2개의 단계 : 스프링 빈 등록 이후, @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;
        }
}

3. 필드 주입

특징

  • 코드가 간결해서 많은 개발자들을 유혹하지만 외부에서 변경이 불가능해서 테스트 하기 힘들다.

치명적인 단점이 있다.

  • DI 프레임워크가 없으면 아무것도 할 수 없다.
    • @Autowired는 스프링 컨테이너가 알아서 주입해주는 것.
    • 순수한 자바코드로 테스트하게되는 상황도 많이 발생하기 때문이다.
  • 사용하지 말자!
    • 애플리케이션의 실제 코드와 관계 없는 테스트 코드
    • 스프링 설정을 목적으로 하는 @configuration 같은 곳에서만 특별한 용도로 사용
      • @configuration은 스프링환경에서만 사용할 것이기 때문
@Component
    public class OrderServiceImpl implements OrderService {
        @Autowired
        private MemberRepository memberRepository;
        @Autowired
        private DiscountPolicy discountPolicy;
}

4. 일반 메서드 주입

특징

  • 한번에 여러 필드를 주입 받을 수 있다.
  • 일반적으로 잘 사용하지 않는다.
@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로 인한 의존관계 자동 주입은 해당 클래스가 빈으로 등록되어 스프링 컨테이너가 관리하는 빈이어야지 가능하다.

참고) 자바빈 프로퍼티 규약

  • setXXX : 수정
  • getXXX : 읽기

** XXX : 필드명

필드에 직접 접근하는 것이 아니라, setXXX, getXXX라는 메서드를 통해서 읽거나, 수정하자.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions