Spring - 애플리케이션 컨텍스트 구성하기 2

 

생성자 주입과 필드 주입에 대하여

Spring의 의존성 주입 (Dependency Injection, DI) - 2


생성자 주입을 이용한 문자열 전달

...
public class ConfigurableMessagProvider implements MessageProvider {

	private String message;

	public ConfigurableMessagProvider(String message) {
		this.message = message;
	}

	...
}
<beans ...>
	<bean id=“messageProvider” class=“com.apress…ConfigurableMessagProvider”>
		<c:message=“MessageProvider에서 제공할 message” />
	</bean>
</beans>

애노테이션을 이용한 생성자 주입

...
@Service(provider)
public class ConfigurableMessagProvider implements MessageProvider {

	private String message;

	@Autowired
	public ConfigurableMessagProvider(@Value("Configurable message") String message) {
		this.message = message
	}

	...
}
  • 아래와 같이 xml 구성을 설정하면 대상 bean에서 @Value 애노테이션은 삭제해도 된다.
<beans ...>
	<context:component-scan base-package="com.apress..." />
	<bean id=“message” class=“java.lang.String”>
		<c:_0=“MessageProvider에서 제공할 message” />
	</bean>
</beans>
  • _0은 생성자 인수에 대한 index이다.
@Service(provider)
public class ConfigurableMessagProvider implements MessageProvider {

	private String message;

	@Autowired
	public ConfigurableMessagProvider(String message) {
		this.message = message
	}

	...
}

인수의 개수와 데이터 타입이 같은 생성자가 여럿 있는 경우

...
public class ConstructorConfusion {

	private String someValue;

	public ConstructorConfusion(String someValue) {
		this.someValue = someValue;
	}

	public ConstructorConfusion(int someValue) {
		this.someValue = Integer.toString(someValue);
	}

	...
}
<beans ...>
	<bean id=“messageProvider” class=“com.apress…ConfigurableMessagProvider”>
		<c:message=“MessageProvider에서 제공할 message” />
	</bean>

	<bean id=“constructorConfusion” class=“com.apress... ConstructorConfusion”>
		<!-- constructor-arg에 type이 int이기 때문에 파라미터 타입이 int인 생성자가 호출된다. -->
		<constructor-arg type="int">
			<value>90</value>
		</constructor-arg>
	</bean>
</beans>
  • 애노테이션을 이용해 호출할 생성자 지정하기
...
public class ConstructorConfusion {

	private String someValue;

	public ConstructorConfusion(String someValue) {
		this.someValue = someValue;
	}

	@Autowired // 하나의 생성자에만 적용할 수 있음
	public ConstructorConfusion(@Value("90") int someValue) {
		this.someValue = Integer.toString(someValue);
	}

	...
}

필드 주입

  • 클래스의 멤버변수에 @Autowired를 적용한다.
  • 접근자가 private여도 필드 주입에는 문제가 없다.
...
@Service(singer)
public class Singer {

	@Autowired
	private Inspiration inspirationBean;

	public void sing() {
		System.out.println(...  + inspirationBean.getLyric());
	}
}
  • 필드 주입의 단점 . 많은 의존성이 생길 경우 리팩터링 시 관심사를 분리하기 어려워 질 수 있다. . 어떤 타입의 의존성이 실제로 필요한지, 의존성이 필수인지 여부가 불명확하다. . final 필드에는 사용할 수 없다. . 의존성을 수동으로 주입해야 해서 테스트 코드 작성이 어렵다. . 외부에서의 변경이 불가능하다(구성 파일에 별다른 설정이 없다).