다양한 의존관계 주입 방법 (생성자 기반 DI)

corncheese·2023년 6월 14일
0

Spring

목록 보기
4/8

스프링에서 의존 관계 주입은 빈의 생성자나 세터 메서드에 인수를 넘기는 방식으로 이루어 진다.

세터 기반 DI (수정자 주입)

세터 기반 DI에서는 property 엘리먼트를 사용해 빈 의존 관계를 설정했다.

  • 선택, 변경이 있는 의존관계에 사용
  • 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용
@Component
public class PersonalBakingService{
	private JmsMessageSender jmsMessageSender;
    private EmailMessageSender emailMessageSender;
    
    // 각 의존관계마다 세터 메서드를 정의한다.
    @Autowired
    public void setJmsMessageSender(JmsMessageSender jmsMessageSender){
    	this.jmsMessageSender = jmsMessageSender;
    }
    
    @Autowired
    public void setEmailMessageSender(EmailMessageSender emailMessageSender){
    	this.emailMessageSender = emailMessageSender;
    }
}

PersonalBakingService 클래스와 의존 관계인 빈 정의

<bean id = "PersonalBankingService" class="PersonalBankingService">
	<property name = "emailMessageSender" ref="emailMessageSender" />
    <property name = "jmsMessageSender" ref = "jmsMessageSender" />
</bean>

생성자 기반 DI

현재 내가 실무에서 사용하고 있는 방법.
이름 그대로 생성자를 통해서 의존 관계를 주입 받는다.

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

생성자 기반 DI에서는 빈의 의존 관계를 빈 클래스 생성자의 인수로 전달한다.

@Component
public class PersonalBankingService{
// 스프링이 PersonalBakingService 객체를 생성할 때 생성자를 주입한다.

	private final JmsMessageSender jmsMessageSender;
    private final EmailMessageSender emailMessageSender;
    
    // 생성자 인수는 클래스의 의존관계를 표현한다.
    // 생성자가 딱 1개 있으면 @Autowired 를 생략해도 자동 주입된다.
    @Autowired
    public PersonalBankingService(JmsMessageSender jmsMessageSender, EmailMessageSender emailMessageSender){
    	this.jsmMessageSender = jmsMessageSender;
        this.emailMessageSender = emailMessageSender;
    }
}

PersonalBankingService 빈 정의

<bean id = "PersonalBankingService" class="PersonalBankingService">
	//contructor-arg 엘리먼트는 PersonalBankingService 인스턴스의 생성자에 전달할 인수를 지정한다. index 속성값이 '0'이면 생성자의 첫번째 인수에 해당
	<constructor-arg index="0" ref="emailMessageSender" />
    <constructor-arg index="1" ref = "jmsMessageSender" />
</bean>

생성자 주입 방식을 사용해야 한다.

< 불변 >

  • 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없다. 오히려 대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안된다.
  • 수정자 주입을 사용하면, setXxx 메서드를 public으로 열어두어야 한다.
  • 누군가 실수로 변경할 수도 있고, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아니다.
  • 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없다. 따라서 불변하게 설계할 수 있다.

< 누락 >

  • 생성자 주입을 사용하면 필드에 final 키워드를 사용하는데, 생성자에서 혹시라도 값이 설정되지 않는 오류를 컴파일 시점에 막아준다.

0개의 댓글