article thumbnail image
Published 2022. 4. 25. 01:26

Auto-wiring (의존 관계 자동 설정)

개념

  • Dependency Injection을 명시적으로 설정하지 않아도 container가 bean의 타입이나 이름을 이용하여 DI를 자동으로 수행하는 기능
  • XML 설정 방법
    • <bean> 엘리먼트에 autowire 속성을 이용하여 자동 설정 방식 지정
    • 모든 bean 객체들에 대해 특정 방식을 적용하려면 <beans> 엘리먼트에 default-autowire 속성 이용
autowire 값 의미
no (default) auto-wiring을 수행하지 않음
byName property와 같은 이름 또는 id 값을 갖는 bean을 찾아 주입 (setter-based injection)
byType property와 같은 타입을 갖는 bean을 찾아 주입 (setter-based injection)
constructor 생성자 호출시 인자(argument)와 같은 타입을 갖는 bean을 찾아 전달
(constructor-based injection)

 

public class Instrumentalist implements Performer {
  private String song; // property (값)
  private Instrument instrument; // property (객체 참조)
  private Company affiliation; // property (객체 참조)

  public Instrumentalist() { } // default constructor
  public Instrumentalist(Instrument instrument) { // constructor 
    this.instrument = instrument;
  }
  public Instrumentalist(Instrument instrument, String song) { // constructor 
    this.instrument = instrument; this.song = song;
  }
  
  public void setSong(String song) { this.song = song; } // setter method
  public void setInstrument(Instrument instrument) { // setter method
    this.instrument = instrument;
  } 
  …
}

 

1. byName (setter-based injection)

<bean id="instrument" class="com.example.springidol.Saxophone" />
<bean id="kenny" class="com.example.springidol.Instrumentalist"
  autowire="byName">
  <property name="song" value="Jingle Bells" />
</bean>

<bean id="kenny" class="com.example.springidol.Instrumentalist">
  <property name="song" value="Jingle Bells" />
  <property name="instrument" ref="instrument" />
</bean>
  • Setter method를 이용하여 property 이름과 같은 id를 갖는 bean을 선택하여 주입
  • 단, 그 bean의 타입이 property의 타입과 같거나 할당가능한 타입이어야 함

 

2. byType (setter-based injection)

<bean id="saxophone" class="com.example.springidol.Saxophone" />
<bean id="kenny" class="com.example.springidol.Instrumentalist"
  autowire="byType">
  <property name="song" value="Jingle Bells" />
</bean>

<bean id="kenny" class="com.example.springidol.Instrumentalist">
  <property name="song" value="Jingle Bells" />
  <property name="instrument" ref="saxophone" />
</bean>
  • saxophone bean은 Instrument를 구현한 클래스의 객체이므로 Instrument 타입 property에 주입 가능
  • Instrument 타입의 객체가 하나만 존재할 경우 그것을 setter method를 통해 주입

 

3. constructor (constructor-based injection)

<bean id="saxophone" class="com.example.springidol.Saxophone" />
<bean id="kenny" class="com.example.springidol.Instrumentalist"
  autowire="constructor" />

<bean id="kenny" class="com.example.springidol.Instrumentalist">
  <constructor-arg ref="saxophone" />
</bean>
  • Instrumentalist 클래스에 Instrument 타입의 인자를 갖는 생성자가 존재하고, saxophone bean이 유일한 Instrument 타입 객체일 때 saxophone bean을 생성자를 통해 주입

 

Auto-wiring과 명시적 설정의 혼합

  • 자동 설정 이용시 일부 property에 대해 명시적인 DI 설정 가능
    • <property>나 <constructor-arg> 이용
    • 명시적인 설정은 auto-wiring보다 우선적으로 적용
<bean id="saxophone" class="com.example.springidol.Saxophone" />
<bean id="kenny" class="com.example.springidol.Instrumentalist" autowire="byType">
  <property name="affiliation" ref="sonymusic"/> <!-- 명시적인 DI 설정 -->
</bean>
  • affiliation property: 명시적으로 지정된 bean(sonymusic)이 주입됨
  • instrument property: DI 설정이 생략되었으므로 byType 방식에 의해 auto-wiring 실행 → saxophone bean 주입

 

주의

  1. byName, byType 방식
    • 주입 가능한 bean이 없을 경우 dependency injection 수행 안 함 → 에러는 발생하지 않지만 의존 객체가 주입되지 않은 상태이므로 나중에 프로그램 실행시 문제가 될 수 있음
  2. byType, constructor 방식
    • 주입 가능한 bean이 여러 개 있을 경우 exception 발생 → NoUniqueBeanDefinitionException
  3. constructor 방식
    • 자동 주입에 사용 가능한 생성자가 여러 개일 경우 exception 발생

 

부모 Bean을 통한 설정 재사용

개념

  • Bean들 사이에 중복되는 설정이 많을 경우 추상 bean을 정의하고 그 설정을 재사용(상속)
  • <bean>에서 abstract, parent 속성 사용
    • abstract="true" : 추상 bean을 정의 (객체 생성 불가)
    • parent="bean ID" : 자식 bean에서 부모(추상) bean의 id 지정
  • 자식 bean은 부모 bean의 class와 property 설정을 상속받음
    • 상속받은 class나 property 설정을 재정의(override)하거나 새로운 property 설정 추가 가능

 

예 1

<bean id="kenny" class="com.example.springidol.Instrumentalist"> → id 외에는 모두 동일

  <property name="song" value="Jingle Bells" />
  <property name="instrument" ref="saxophone" />
</bean>
<bean id="david" class="com.example.springidol.Instrumentalist"> → id 외에는 모두 동일
  <property name="song" value="Jingle Bells" />
  <property name="instrument" ref="saxophone" />
</bean>

<bean id="saxophonist" class="com.example.springidol.Instrumentalist"
  abstract="true"> 추상 bean
  <property name="instrument" ref="saxophone" />
  <property name="song" value="Jingle Bells" />
</bean>
<bean id="kenny" parent="saxophonist" /> 
<bean id="david" parent ="saxophonist" /> 
<bean id="frank" parent ="saxophonist" >
  <property name="song" value="May had a little ramb" /> 
</bean>
  • 6~8행: song과 instrument에 대한 DI 설정을 상속받음

 

예 2

<bean id="taylor" class="com.example.springidol.Vocalist">
  <property name="song" value="Somewhere Over the Rainbow" /> → 동일
</bean>
<bean id="stevie" class="com.example.springidol.Instrumentalist">
  <property name="song" value="Somewhere Over the Rainbow" /> → 동일
  <property name="instrument" ref="guitar" />
</bean>

<bean id="basePerformer" abstract="true"> 
  <property name="song" value="Somewhere Over the Rainbow" />
</bean> 
<bean id="taylor" class="com.example.springidol.Vocalist" 
  parent="basePerformer">
<bean id="stevie" class="com.example.springidol.Instrumentalist" 
  parent="basePerformer">
  <property name="instrument" ref="guitar" /> 
</bean>
  • 1행: 부모 bean의 class 설정 생략 가능
  • 4, 6행: class 설정
  • 8행: 새로운 DI 설정 추가

 

'프로그래밍 > Spring' 카테고리의 다른 글

[Spring] DI - XML 기반 설정  (0) 2022.04.24
[Spring] Spring MVC(2)  (0) 2022.04.22
[Spring] Spring MVC(1)  (0) 2022.04.17
[Spring] Spring DI  (0) 2022.04.01
복사했습니다!