의존성 주입(Dependency Injection, DI)은 객체 지향 프로그래밍에서 객체의 의존성을 외부에서 주입받는 방식입니다. 이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다. DI를 구현하는 세 가지 주요 방법은 생성자 주입(Constructor Injection), 메서드 주입(Method Injection), 필드 주입(Field Injection)입니다.
세 가지 주요 DI 방법
- 생성자 주입(Constructor Injection):
- 의존성을 생성자 매개변수로 전달받아 주입합니다.
- 의존성이 반드시 필요할 때 사용하며, 주입받는 의존성이 변경되지 않도록 보장합니다.
- 메서드 주입(Method Injection):
- 의존성을 메서드 매개변수로 전달받아 주입합니다.
- 주로 설정 메서드를 통해 선택적인 의존성을 주입할 때 사용합니다.
- 필드 주입(Field Injection):
- 의존성을 클래스의 필드에 직접 주입합니다.
- 가장 간단한 방식이지만, 테스트와 리팩토링이 어려워질 수 있습니다.
팩토리 메서드에 의한 의존성 주입
팩토리 메서드 패턴은 객체 생성 로직을 별도의 메서드로 캡슐화하여 클라이언트 코드와 객체 생성 로직을 분리합니다. 이를 통해 의존성 주입을 보다 유연하게 구현할 수 있습니다.
예제: 팩토리 메서드를 통한 의존성 주입
다음은 스프링 프레임워크를 사용하여 팩토리 메서드에 의한 의존성 주입을 구현하는 예제입니다.
서비스 인터페이스와 구현 클래스
public interface MessageService {
void sendMessage(String message);
}
public class EmailMessageService implements MessageService {
@Override
public void sendMessage(String message) {
System.out.println("Email message: " + message);
}
}
팩토리 클래스
public class ServiceFactory {
public MessageService createMessageService() {
return new EmailMessageService();
}
}
의존성을 주입받는 클래스
public class MessageProcessor {
private MessageService messageService;
// 생성자 주입
public MessageProcessor(MessageService messageService) {
this.messageService = messageService;
}
public void processMessage(String message) {
messageService.sendMessage(message);
}
}
Spring 설정 파일 (XML)
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- ServiceFactory 빈 정의 -->
<bean id="serviceFactory" class="com.example.ServiceFactory"/>
<!-- MessageService 빈 정의 -->
<bean id="messageService" factory-bean="serviceFactory" factory-method="createMessageService"/>
<!-- MessageProcessor 빈 정의 -->
<bean id="messageProcessor" class="com.example.MessageProcessor">
<constructor-arg ref="messageService"/>
</bean>
</beans>
애플리케이션 클래스
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Application {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MessageProcessor processor = context.getBean("messageProcessor", MessageProcessor.class);
processor.processMessage("Hello, World!");
}
}
세 가지 주요 DI 방법의 설명
- 생성자 주입(Constructor Injection):
MessageProcessor
클래스의 생성자를 통해MessageService
를 주입받습니다.- 생성자 주입은 객체가 생성될 때 모든 필수 의존성을 주입받아야 하므로, 의존성 주입이 완료된 이후에 객체가 완전한 상태가 됩니다.
- 장점: 의존성이 변하지 않으며, 객체의 불변성을 유지할 수 있습니다. 필수 의존성을 강제할 수 있습니다.
- 단점: 의존성이 많아지면 생성자의 매개변수가 많아질 수 있습니다.
- 메서드 주입(Method Injection):
MessageProcessor
클래스에서setMessageService
와 같은 설정 메서드를 통해 선택적인 의존성을 주입할 수 있습니다.- 메서드 주입은 선택적인 의존성을 주입하거나, 의존성이 변경될 수 있는 경우에 사용됩니다.
- 장점: 선택적인 의존성을 주입할 수 있습니다. 여러 의존성을 설정하는데 유연합니다.
- 단점: 객체가 완전한 상태가 아닌 경우가 발생할 수 있습니다. 의존성이 누락될 위험이 있습니다.
- 필드 주입(Field Injection):
MessageProcessor
클래스의 필드에 직접@Autowired
애너테이션을 사용하여 의존성을 주입합니다.- 필드 주입은 가장 간단한 방식이지만, 테스트와 리팩토링이 어려울 수 있습니다.
- 장점: 간단하고 명료합니다.
- 단점: DI 프레임워크에 강하게 의존하며, 테스트와 리팩토링이 어려울 수 있습니다.
결론
스프링 IoC 컨테이너는 다양한 방법을 통해 의존성을 주입할 수 있습니다. 생성자 주입, 메서드 주입, 필드 주입을 통해 객체 간의 결합도를 낮추고, 코드의 유연성과 테스트 용이성을 높일 수 있습니다. 팩토리 메서드를 사용하여 의존성을 주입하면, 객체 생성 로직을 캡슐화하고 유연성을 높일 수 있습니다. 이러한 다양한 DI 방법을 적절히 활용하면, 더 유연하고 유지보수 가능한 애플리케이션을 개발할 수 있습니다.
'Spring Framework' 카테고리의 다른 글
빈 팩토리(BeanFactory)와 팩토리 빈(FactoryBean) (0) | 2024.08.11 |
---|---|
스프링 프레임워크의 핵심 3대 요소 (0) | 2024.08.11 |
스프링 IoC(Inversion of Control) 컨테이너 (0) | 2024.08.07 |
JUnit 단위 테스트 라이프사이클 (0) | 2024.08.07 |
어썰션(Assertion)과 어썰트(Assert) (1) | 2024.08.07 |