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 필드에는 사용할 수 없다. . 의존성을 수동으로 주입해야 해서 테스트 코드 작성이 어렵다. . 외부에서의 변경이 불가능하다(구성 파일에 별다른 설정이 없다).