Ioc
제어의 역전이라는 개념으로, 객체의 생성과 관리, 그리고 의존성 주입을 개발자가 아닌 프레임워크가 담당하는 것을 의미
일반적으로 객체는 다른 객체를 직접 생성하거나 제어하지 않고, 컨테이너 또는 프레임워크가 객체의 생성과 라이프사이클을 관리 IoC가 이러한 역할.
IoC동작 방식
Bean 정의 읽기
설정 파일(XML, Java Config 등)을 통해 Bean 정의를 읽어들임
Bean 생성 및 초기화
Bean 정의에 따라 객체를 생성하고, 필요한 의존성을 주입
라이프 사이클 관리
Bean의 초기화, 사용, 소멸 단계를 관리하며, 필여한 경우 후처리기 등을 통해 추가 작업을 수행
Spring에서는 Bean의 생명주기를 관리하기위해 다양한 스코프를 지원,
DI(Dependency Injection)
IoC의 구체적인 구현 방법 중 하나.
객체가 자신의 의존성을 직접 생성하지 않고, 외부에서 주입받는 방식
의존성의 관리를 프레임워크에 맡기고, 객체간의 결합도를 낮춤
DI 방식 예제
의존성 인터페이스 생성
public interface GreetingService {
String greet();
}
@Service
public class GreetingServiceImpl implements GreetingService {
@Override
public String greet() {
return "Hello, World!";
}
}
생성자 주입 방식
@RestController
public class MyController {
private final GreetingService greetingService;
@Autowired
public MyController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/greet")
public String greet() {
return greetingService.greet();
}
}
- Autowired 어노테이션을 사용하여 Spring IoC 컨테이너가 GreetingService의 구현체를 주입
필드 주입 방식
@RestController
public class MyController {
@Autowired
private GreetingService greetingService;
@GetMapping("/greet")
public String greet() {
return greetingService.greet();
}
}
- Autowired어노테이션을 사용하여 GreetingService 필드에 직접 주입
- 코드가 간결해지지만 생성자 주입에 비해 테스트가 어렵고, 주입 시점이 명확하지 않음
세터 주입 방식
@RestController
public class MyController {
private GreetingService greetingService;
@Autowired
public void setGreetingService(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/greet")
public String greet() {
return greetingService.greet();
}
}
- 세터 메서드를 통해 GreetingService 의존성을 주입
- 의존성을 선택적으로 주입할 수 있어 유연성이 높지만, 초기화 과정이 추가
이점
모듈화
각 클래스가 독립적으로 관리되고, 필요한 의존성만 주입받아 기능을 수행
테스트 용이성
각 컴포넌트를 독립적으로 테스트할 수 있으며, Mock 객체를 활용해 의존성을 주입받을 수 있음
유지보수성
의존성 관리가 중앙화되어 있어 코드 변경이 용이하고, 전체 애플리케이션 구조를 이해하기 쉬움
Share article