LUMI_dev
IoC(제어의 역전)와 DI(의존성 주입) 본문
IoC(제어의 역전)와 DI(의존성 주입)은 SOLID 원칙 그리고 GoF의 디자인 패턴과 같은 설계 원칙 및 디자인 패턴
Ioc = 설계 원칙
DI = 디자인 패턴
0. 설계 원칙? 디자인 패턴?
더보기


설계 원칙 | 디자인 패턴 |
김치 볶음밥 맛있게 만드는 방법 | 김치 볶음밥 레시피 |
🧑🍳 맛있는 김치 볶음밥을 만들기 위한 원칙
|
🍳 맛있는 김치 볶음밥을 만들기 위한 황금 레시피
|
Spring Docs

DI 패턴을 사용하여 IoC 설계 원칙을 구현하고 있다.
1. DI 를 이해하려면 '의존성'을 알아야 한다.
결합도가 높은 코드
public class Consumer {
void eat() {
Chicken chicken = new Chicken();
chicken.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.eat();
}
}
class Chicken {
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
- 문제점 : 만약 Consumer가 치킨이 아니라 피자를 먹고 싶어한다면? → 많은 코드의 변경이 불가피함
- 해결방법 : Java의 Interface를 활용하여 해결할 수 있음
Interface 다형성의 원리를 사용하여 약한 결합 및 약한 의존성으로 수정된 코드
public class Consumer {
void eat(Food food) {
food.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.eat(new Chicken());
consumer.eat(new Pizza());
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
2. 주입이란?
: 여러 방법을 통해 필요로 하는 객체를 해당 객체에 전달하는 것
: 외부에서 미리 만든 객체를 주입하는 것이 DI 패턴
방법 1) 필드에 직접 주입
: Food를 Consumer에 포함시키고 Food에 필요한 객체를 주입 받아 사용하는 방법
public class Consumer {
Food food;
void eat() {
this.food.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.food = new Chicken();
consumer.eat();
consumer.food = new Pizza();
consumer.eat();
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
방법 2) 메서드를 통한 주입
: set 메서드를 사용하는 방법
public class Consumer {
Food food;
void eat() {
this.food.eat();
}
public void setFood(Food food) {
this.food = food;
}
public static void main(String[] args) {
Consumer consumer = new Consumer();
consumer.setFood(new Chicken());
consumer.eat();
consumer.setFood(new Pizza());
consumer.eat();
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
방법 3) 생성자를 통한 주입
public class Consumer {
Food food;
public Consumer(Food food) {
this.food = food;
}
void eat() {
this.food.eat();
}
public static void main(String[] args) {
Consumer consumer = new Consumer(new Chicken());
consumer.eat();
consumer = new Consumer(new Pizza());
consumer.eat();
}
}
interface Food {
void eat();
}
class Chicken implements Food{
@Override
public void eat() {
System.out.println("치킨을 먹는다.");
}
}
class Pizza implements Food{
@Override
public void eat() {
System.out.println("피자를 먹는다.");
}
}
3. 제어의 역전이란?(IoC)
수정 전 코드 : Consumer이 직접 Food를 만들어 먹었기 때문에 추가적인 요리 준비(코드 변경) 불가
(제어의 흐름) Consumer → Food
수정 후 코드 : Food를 Consumer에게 전달해주는 방식
(제어의 흐름) Food → Consumer (역전)
'스파르타 코딩 클럽 | 자바 심화 과정 > Spring Master (입문 주차)' 카테고리의 다른 글
JPA CORE - #1. DB의 ORM / JPA / 하이버네이트 (0) | 2025.01.26 |
---|---|
IoC Container와 Bean (0) | 2025.01.26 |
Jackson이란? (0) | 2025.01.23 |
Spring MVC #1. MVC 디자인 패턴/Servlet (서블릿)/Front Controller (1) | 2025.01.22 |
application.properties 및 포트 번호(server.port) 바꾸는 법 (0) | 2025.01.22 |