F-LAB JAVA · 5주차 · Phase 7 · 제어의 역전 (IoC)
이 Unit을 끝내면 다음을 답할 수 있어야 한다.
라이브러리는 내 코드가 호출하여 제어권이 나에게 있고, 프레임워크는 프레임워크가 내 코드를 호출하여 제어권이 프레임워크에 있는 (IoC) 점이 결정적 차이다.
라이브러리 — 내가 필요할 때 꺼내 쓰는 도구로, 호출 방향이 "내 코드 → 라이브러리" 이고 제어의 흐름을 내가 가진다 (망치를 내가 휘두름).
프레임워크 — 내가 그 안에 들어가 일하는 틀로, 호출 방향이 "프레임워크 → 내 코드" 이고 제어의 흐름을 프레임워크가 가진다 (공장에 들어가 정해진 자리에서 일함).
이 차이를 Hollywood Principle ("Don't call us, we'll call you" — 우리에게 전화하지 마라, 우리가 부르겠다) 로 표현하며, 이것이 곧 IoC 다.
jQuery 는 내가 호출하므로 라이브러리, Spring 은 내가 만든 객체 (빈) 와 메서드 (컨트롤러) 를 Spring 이 생성·호출하므로 프레임워크다.
라이브러리 vs 프레임워크:
라이브러리 (망치):
- 내가 필요할 때 꺼냄
- 내가 휘두름 (호출)
- 제어가 나에게
- 내 코드 → 망치(라이브러리)
프레임워크 (공장):
- 내가 공장에 들어감
- 공장이 정한 자리에서 일함
- 공장이 "이제 네 차례" (호출)
- 제어가 공장
- 공장(프레임워크) → 내 코드
Hollywood Principle:
- "전화하지 마, 우리가 부를게"
- 배우(내 코드)가 감독(프레임워크)에게 전화 X
- 감독이 "액션!" 외칠 때 연기
호출 방향이 결정:
- 라이브러리: 내가 부름
- 프레임워크: 부름당함 (IoC)
→ 라이브러리(망치, 내가 호출) vs 프레임워크(공장, 호출당함=IoC).
1. 프레임워크 vs 라이브러리 정의
2. 누가 흐름을 제어
3. 호출 방향
4. 망치 vs 공장
5. Hollywood Principle
6. jQuery는?
7. Spring이 프레임워크인 이유
8. 경계가 모호한 경우
9. 면접 + 자기 점검
라이브러리 (Library):
재사용 가능한 코드 모음:
- 내가 호출
- 필요한 기능 가져다 씀
- 제어권 = 나
프레임워크 (Framework):
애플리케이션 골격:
- 프레임워크가 호출
- 내 코드를 끼워 넣음
- 제어권 = 프레임워크
핵심 차이:
제어권:
- 라이브러리: 나
- 프레임워크: 프레임워크
→ IoC 여부
// 라이브러리 사용 (내가 호출)
public class FreightCalculator {
public BigDecimal calculate(Shipment s) {
// Apache Commons (라이브러리) — 내가 호출
BigDecimal weight = s.getWeight();
return weight.multiply(BigDecimal.TEN);
// StringUtils.isEmpty(...) 등 내가 호출
}
}
// 프레임워크 (Spring 이 호출)
@RestController
public class ShipmentController {
@GetMapping("/shipments/{id}")
public Shipment get(@PathVariable Long id) {
// 이 메서드를 Spring 이 호출 (제어가 Spring)
return null;
}
}
프레임워크와 라이브러리의 차이는?
답:
1. 라이브러리:
프레임워크:
핵심:
IoC:
제어의 흐름:
"프로그램 실행 흐름을 누가?"
라이브러리:
- 내 코드가 흐름 제어
- 라이브러리 호출
프레임워크:
- 프레임워크가 흐름 제어
- 내 코드 호출
// 라이브러리 — 내가 흐름 제어
public void process() {
// 내가 순서대로 호출
String data = readFile(); // 내 흐름
String result = library.parse(data); // 라이브러리 호출
saveResult(result); // 내 흐름
}
// 내가 흐름 결정
// 프레임워크 — 프레임워크가 흐름 제어
@RestController
public class Controller {
@GetMapping("/api")
public String handle() {
// Spring 이 이 메서드를 적절한 때 호출
// 흐름은 Spring 이
return "result";
}
}
// 프레임워크가 흐름 결정
| 항목 | 라이브러리 | 프레임워크 |
|---|---|---|
| 흐름 제어 | 내 코드 | 프레임워크 |
| 호출 | 내가 함 | 당함 |
| IoC | X | O |
// 라이브러리 흐름 (내가 제어)
public class ShipmentBatch {
public void run() {
List<Shipment> shipments = loadShipments(); // 내 흐름
for (Shipment s : shipments) {
BigDecimal freight = calculator.calculate(s); // 라이브러리 호출
save(s, freight); // 내 흐름
}
// 내가 전체 흐름 제어
}
}
// 프레임워크 흐름 (Spring 제어)
@Service
public class ShipmentService {
@Scheduled(cron = "0 0 * * * *") // Spring 이 시간 되면 호출
public void processBatch() {
// 흐름(언제 실행)은 Spring 이 제어
}
@EventListener
public void onCreated(ShipmentEvent e) { // Spring 이 이벤트 시 호출
// 흐름은 Spring 이
}
}
record ShipmentEvent(Long id) {}
누가 흐름을 제어하는가?
답:
1. 흐름 제어:
라이브러리:
프레임워크:
IoC:
호출 방향:
라이브러리:
내 코드 → 라이브러리
(내가 호출)
프레임워크:
프레임워크 → 내 코드
(호출당함)
라이브러리 방향:
[내 코드] → 호출 → [라이브러리]
- 내가 능동
- 라이브러리는 수동
프레임워크 방향:
[프레임워크] → 호출 → [내 코드]
- 프레임워크 능동
- 내 코드 수동 (끼워짐)
방향이 IoC:
프레임워크 → 내 코드:
- 제어가 프레임워크
- 내 코드 호출당함
- = IoC
→ 호출 방향 역전
// 호출 방향
// 라이브러리: 내 코드 → 라이브러리
public class ShipmentLogic {
public void calculate(Shipment s) {
BigDecimal result = MathUtils.round(s.getWeight()); // 내가 호출
// 내 코드 → MathUtils (라이브러리)
}
}
// 프레임워크: Spring → 내 코드
@Component
public class ShipmentHandler {
@KafkaListener(topics = "shipments") // Spring 이 메시지 시 호출
public void handle(String message) {
// Spring → 이 메서드 (호출당함)
}
}
// 호출 방향이 반대 (IoC)
호출 방향의 차이는?
답:
1. 라이브러리:
프레임워크:
방향:
IoC:
망치 (라이브러리):
- 필요할 때 꺼냄
- 내가 휘두름
- 내가 통제
→ 내 도구
공장 (프레임워크):
- 내가 들어감
- 정해진 자리에서 일함
- 공장이 통제
→ 정해진 틀
비유 정리:
라이브러리 (망치):
- 내가 주체
- 도구 사용
프레임워크 (공장):
- 공장이 주체
- 틀 안에서 작업
선택 vs 따름:
라이브러리:
- 내가 선택해서 사용
- 자유
프레임워크:
- 규칙 따름
- 제약 (틀)
// 망치 (라이브러리) — 내가 사용
public class FreightUtil {
public BigDecimal calc(Shipment s) {
// 라이브러리(망치)를 내가 골라 씀
return BigDecimalUtil.round(s.getWeight(), 2);
}
}
// 공장 (프레임워크) — 틀 안에서
@RestController // Spring 의 틀
@RequestMapping("/api/shipments")
public class ShipmentController {
// Spring 이 정한 규칙(@GetMapping 등) 따름
@GetMapping("/{id}")
public Shipment get(@PathVariable Long id) {
return null;
// 공장(Spring)의 틀 안에서 작업
}
}
class BigDecimalUtil {
static BigDecimal round(BigDecimal v, int scale) { return v; }
}
망치 vs 공장 비유는?
답:
1. 망치:
공장:
주체:
선택 vs 따름:
Hollywood Principle:
"Don't call us, we'll call you"
"우리에게 전화하지 마라,
우리가 부르겠다"
→ 프레임워크가 내 코드 호출
의미:
배우(내 코드):
- 감독(프레임워크)에게 전화 X
- 감독이 "액션" 외칠 때 연기
→ 제어가 프레임워크
IoC 표현:
Hollywood Principle = IoC:
- 내가 호출 X
- 호출당함
- 제어 역전
→ 같은 개념
// 콜백 등록 (Hollywood)
button.addClickListener(event -> {
// 내가 등록만
// 클릭 시 시스템이 호출 (we'll call you)
});
// 등록: 내가, 호출: 시스템
// Hollywood Principle (ILIC)
// "전화하지 마, 우리가 부를게"
@Component
public class ShipmentEventHandler {
// 내가 호출 X, Spring 이 이벤트 시 호출
@EventListener
public void onShipmentCreated(ShipmentCreatedEvent event) {
// "we'll call you" — Spring 이 부름
processNewShipment(event.shipmentId());
}
// 스케줄: 내가 호출 X, Spring 이 시간 되면
@Scheduled(fixedRate = 60000)
public void checkPendingShipments() {
// Spring 이 1분마다 호출
}
private void processNewShipment(Long id) { }
}
record ShipmentCreatedEvent(Long shipmentId) {}
// 내 코드를 Spring 이 호출 (Hollywood = IoC)
Hollywood Principle이란?
답:
1. 원칙:
의미:
IoC:
예:
jQuery 는?
라이브러리:
- 내가 호출 ($("...").click())
- 제어가 나
- 필요할 때 사용
왜 라이브러리:
jQuery:
- $(selector) 내가 호출
- DOM 조작 내가 지시
- 흐름 제어 = 나
→ 라이브러리
vs Angular (프레임워크):
Angular:
- 프레임워크 구조
- 생명주기 (프레임워크 호출)
- 제어 = Angular
React:
- 라이브러리 (자칭)
- 하지만 프레임워크적 (렌더링 제어)
- 경계 모호
판단 기준:
"누가 호출?"
- 내가 → 라이브러리
- 그것이 → 프레임워크
"제어가 어디?"
- 나 → 라이브러리
- 그것 → 프레임워크
// 판단 기준 적용
// 라이브러리 (내가 호출)
public class Example {
public void useLib() {
// Jackson (라이브러리) — 내가 호출
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(shipment); // 내가 호출
// → 라이브러리
}
}
// 프레임워크 (Spring 이 호출)
@RestController
public class Example2 {
// Spring 이 요청 시 호출 → 프레임워크
@PostMapping("/shipments")
public void create(@RequestBody Shipment shipment) {
// Spring 이 JSON 파싱 후 호출
}
}
// Jackson: 라이브러리 (내가 호출)
// Spring MVC: 프레임워크 (호출당함)
jQuery는 라이브러리인가 프레임워크인가?
답:
1. jQuery:
왜:
vs Angular:
판단:
Spring 이 프레임워크인 이유:
Spring 이:
- 객체 생성 (빈)
- 메서드 호출 (컨트롤러)
- 생명주기 관리
→ 제어가 Spring (IoC)
빈 생성·관리:
Spring 컨테이너:
- 빈 생성 (내가 X)
- 의존성 주입
- 생명주기
→ 객체 제어가 Spring
// Spring 이 메서드 호출
@RestController
public class ShipmentController {
@GetMapping("/shipments") // Spring 이 요청 시 호출
public List<Shipment> list() {
return null;
}
// 내가 호출 X, Spring 이 호출
}
// Spring 이 생명주기 관리
@Component
public class ShipmentService {
@PostConstruct // Spring 이 생성 후 호출
public void init() { }
@PreDestroy // Spring 이 소멸 전 호출
public void cleanup() { }
}
// 생명주기 콜백을 Spring 이 호출
// Spring 의 IoC (전방위)
@Service
public class ShipmentService {
private final ShipmentDao shipmentDao;
// 1. Spring 이 생성 + 의존성 주입
public ShipmentService(ShipmentDao shipmentDao) {
this.shipmentDao = shipmentDao; // Spring 이 주입
}
// 2. Spring 이 생명주기 호출
@PostConstruct
public void init() {
log.info("초기화"); // Spring 이 호출
}
}
@RestController
public class ShipmentController {
private final ShipmentService service;
public ShipmentController(ShipmentService service) {
this.service = service; // Spring 주입
}
// 3. Spring 이 요청 시 메서드 호출
@GetMapping("/shipments")
public List<Shipment> list() {
return service.findAll();
}
}
// 생성·주입·호출·생명주기 모두 Spring (IoC)
// → Spring = 프레임워크
Spring이 프레임워크인 이유는?
답:
1. IoC:
빈 생성·관리:
메서드 호출:
생명주기:
경계 모호:
일부는 둘 다:
- 라이브러리 + 프레임워크적
- 사용 방식에 따라
예: React, Spring 일부
React:
자칭 라이브러리:
- UI 컴포넌트
프레임워크적:
- 렌더링 제어
- 생명주기
→ 경계 모호
사용 방식:
같은 도구도:
- 라이브러리처럼 (내가 호출)
- 프레임워크처럼 (호출당함)
→ 맥락에 따라
본질은 IoC:
구분 기준:
- IoC 여부
- 제어가 어디
프레임워크적 = IoC 강함
라이브러리적 = IoC 약함
// Spring 도 라이브러리처럼 쓸 수 있음
// 프레임워크처럼 (IoC, 일반적)
@RestController
public class Controller {
@GetMapping("/api") // Spring 이 호출
public String handle() { return ""; }
}
// 라이브러리처럼 (내가 호출)
public class ManualUsage {
public void use() {
// ApplicationContext 를 내가 직접
ApplicationContext ctx =
new AnnotationConfigApplicationContext(Config.class);
ShipmentDao dao = ctx.getBean(ShipmentDao.class); // 내가 호출
// 라이브러리처럼 사용
}
}
// 같은 Spring, 사용 방식 다름
// 본질: IoC 여부로 판단
@Configuration
class Config {}
둘의 경계가 모호한 경우는?
답:
1. 모호:
사용 방식:
본질:
기준:
| Q | 핵심 답변 |
|---|---|
| 프레임워크 vs 라이브러리? | 제어권 (IoC 여부) |
| 누가 흐름 제어? | 라이브러리: 나, 프레임워크: 그것 |
| 호출 방향? | 내→라이브러리, 프레임워크→내 |
| 망치 vs 공장? | 휘두름 vs 틀 안 |
| Hollywood Principle? | "우리가 부를게" |
| jQuery? | 라이브러리 |
| Spring 프레임워크? | 생성·호출·생명주기 |
| 본질? | IoC |
| 경계 모호? | 사용 방식 |
| IoC? | 프레임워크 = 제어 역전 |
답:
답:
답:
답:
답:
1. 핵심 차이
2. 호출 방향과 비유
3. 판단
이번 Unit에서 프레임워크 vs 라이브러리를 봤다면, 다음은 IoC 컨테이너 (Phase 7 마지막).
🌱 Phase 7 — 제어의 역전 (IoC)
✅ Unit 7.1 IoC 개념 ★깊이
✅ Unit 7.2 프레임워크 vs 라이브러리 ← 여기
⏭ Unit 7.3 IoC 컨테이너의 역할 — Phase 7 완주
✅ Part A — 동시성 마무리 (7 Unit)
🌱 Part B — 토비의 스프링
✅ Phase 3~6 (12 Unit)
🌱 Phase 7 — IoC (2/3 진행)
총: 21/26 Unit