참고: 김영한, 스프링 핵심 원리, https://www.inflearn.com/course/lecture?courseSlug=%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8
IoC, Inversion of Control, 제어의 역전
프로그램의 제어를 직접 제어하는 것이 아닌 외부에서 관리하는 것을 말한다.
IoC를 적용하지 않은 기존의 프로그램들은 구현체가 필요한 객체들을 직접 생성, 연결, 실행한다. 즉, 구현체가 제어의 흐름을 관제한다. 하지만 IoC 개념이 적용된 프로그램에서 제어의 흐름은 다른 객체(혹은 프레임워크)가 관제한다. 각 객체들은 내부의 필요한 구현체들이 어떤 구현체들로 구성될지는 모른다.
IoC 적용 시 효과
- 코드의 결합도가 낮아진다.
- IoC 적용 전: 객체의 생성, 객체 간 의존성을 개발자가 직접 코드 안에서 관리 ➡️ 코드의 결합도가 높음
- IoC 적용 후: 특정 객체 혹은 프레임워크에서 객체의 생성, 의존성을 관리하므로, 객체들은 내부의 구현체들을 모름. ➡️ 코드의 결합도가 낮음
- 유연성과 확장성이 증가한다.
- IoC의 적용으로 결합도가 낮아지므로, 유지보수성(유연성, 확장성)이 증가
- 테스트에 용이해진다.
- IoC에 의해 결합도가 낮아지므로, 유닛 테스트시 필요한 의존성만 주입해 테스트할 수 있음.
스프링의 IoC 컨테이너
스프링은 'ApplicationContext' 라는 IoC 컨테이너를 제공한다. 각 컴포넌트들은 IoC 컨테이너에 Bean 객체로 생성이 되고, IoC 컨테이너에서 의존성을 관리한다.
DI, 의존성 주입의 3가지 방법
스프링에서는 아래 3가지 방법으로 의존성을 주입할 수 있다.
1. 생성자 주입(Constructor Injection)
객체를 생성할 때 생성자를 통해 의존성을 주입하는 방법
- 의존성의 불변 보장(의존성이 바뀌지 않고 고정)
- 의존성 누락을 방지(생성 시 바로 의존성 주입이 되므로 의존성 누락을 방지)
@Service
public class ExampleService {
}
@Controller
public class ExampleController {
private final ExampleService exampleService;
@Autowired
public ExampleController(ExampleService exampleService) {
this.exampleService = exampleService;
}
}
2. 세터 주입(Setter Injection)
객체 생성 후 세터 메서드를 통해 주입하는 방법
- 의존관계를 변경할 수 있음
@Service
public class ExampleService {
}
@Controller
public class ExampleController {
private ExampleService exampleService;
@Autowired
public void setExampleController(ExampleService exampleService) {
this.exampleService = exampleService;
}
}
3. 필드 주입(Field Injection)
객체의 필드에서 직접 의존성을 주입하는 방법
- 객체가 생성된 후, 리플렉션을 통해 의존성이 주입됨
- 리플렉션으로 인한 단점들(성능 저하, 보안 문제 등) 때문에 권장 X
- 순환 의존의 발견을 찾기 어려움 (생성자 주입의 경우, 컴파일 시 발견 가능)
//필드 주입 예시
@Service
public class ExampleService {
}
@Controller
public class ExampleController {
@Autowired
private ExampleService exampleService;
}
//순환 의존 예시
@Component
public class ClassA {
@Autowired
private ClassB classB;
}
@Component
public class ClassB {
@Autowired
private ClassA classA;
}
'스프링' 카테고리의 다른 글
[Spring] 디자인 패턴 - 템플릿 메서드 패턴 (0) | 2024.04.08 |
---|---|
[Spring] 동시성 문제 - ThreadLocal로 개선 (0) | 2024.04.07 |
[Spring] 객체 지향 설계 SOLID 개념과 적용 예시 (0) | 2024.03.25 |
스프링 - WebSocket (0) | 2024.03.07 |
[WAS] 쓰레드 풀 (0) | 2024.03.07 |