728x90
DI(Dependency Injection)는 객체 지향 프로그래밍에서 객체 간의 의존성을 줄이고 결합도를 낮추기 위한 디자인 패턴입니다. Java에서는 주로 프레임워크(Spring 등)를 사용하여 DI를 구현하는데, 이는 객체 간의 의존 관계를 코드에서 명시적으로 만들지 않고 프레임워크가 자동으로 주입해 주는 방식입니다.
DI의 개념
DI는 객체 A가 객체 B를 직접 생성하지 않고, 외부에서 객체 B를 주입(inject)받는 방식입니다. 이렇게 하면 객체 간의 결합도가 낮아져 코드의 유연성과 재사용성이 높아집니다. DI의 주요 방식은 다음과 같습니다.
- Constructor Injection: 생성자를 통해 의존성을 주입
- Setter Injection: setter 메서드를 통해 의존성을 주입
- Field Injection: 필드에 직접 의존성을 주입
코드 예시
1. Constructor Injection
// Service 클래스 (의존성 대상)
public class UserService {
public void process() {
System.out.println("Processing user service...");
}
}
// Controller 클래스 (의존성을 주입받는 클래스)
public class UserController {
private final UserService userService;
// 생성자를 통한 의존성 주입
public UserController(UserService userService) {
this.userService = userService;
}
public void handleRequest() {
userService.process();
}
}
// Main 클래스 (의존성을 주입해주는 부분)
public class MainApp {
public static void main(String[] args) {
// 외부에서 의존성을 주입
UserService userService = new UserService();
UserController userController = new UserController(userService);
userController.handleRequest();
}
}
2. Setter Injection
// Service 클래스
public class UserService {
public void process() {
System.out.println("Processing user service...");
}
}
// Controller 클래스
public class UserController {
private UserService userService;
// Setter 메서드를 통한 의존성 주입
public void setUserService(UserService userService) {
this.userService = userService;
}
public void handleRequest() {
userService.process();
}
}
// Main 클래스
public class MainApp {
public static void main(String[] args) {
UserService userService = new UserService();
UserController userController = new UserController();
// 외부에서 의존성 주입
userController.setUserService(userService);
userController.handleRequest();
}
}
3. Field Injection (Spring에서 자주 사용됨)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
// Service 클래스
@Service
public class UserService {
public void process() {
System.out.println("Processing user service...");
}
}
// Controller 클래스
@Controller
public class UserController {
// 필드에 직접 의존성 주입
@Autowired
private UserService userService;
public void handleRequest() {
userService.process();
}
}
// Main 클래스
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserController userController = context.getBean(UserController.class);
userController.handleRequest();
}
}
DI의 장점
- 테스트 용이성: Mock 객체나 스텁을 주입해 테스트 가능.
- 유연성 증가: 의존성을 외부에서 주입받기 때문에 새로운 구현체로 쉽게 변경 가능.
- 결합도 감소: 클래스가 구체적인 구현체에 의존하지 않고 인터페이스 또는 추상 클래스에 의존.
728x90
'프로그래밍 > Java' 카테고리의 다른 글
Map 인터페이스의 사용 (1) | 2024.10.26 |
---|---|
List와 ArrayList의 개념과 차이 (0) | 2024.10.25 |
@Controller와 @RestController의 차이 (0) | 2024.10.23 |
Portable Service Abstraction개념 활용 테스트 코드 작성 (0) | 2024.10.22 |
BeanFactory와ApplicationContext의 개념과 차이(스프링IOC) (1) | 2024.10.21 |