SlideShare a Scribd company logo
1 of 13
Download to read offline
이재윤
DI Container 구현해보기
https://github.com/zz9z9/my-di-container
Intro
의존성(의존관계) 주입이란 ?
• 호출할 객체를 직접 선언하는게 아니라 런타임시 외부에서 주입해주는 것

• 이게 가능한 이유는 구체적인 객체가 아닌 인터페이스에 의존하기 때문에

• 따라서, 객체 간의 의존관계를 정적인 클래스 관계에서는 알 수 없다.
의존성(의존관계) 주입이 필요한 이유
• DIP, SRP, OCP를 지킨 좋은 설계를 가능하게 해준다.
✓ 구체적인 객체에 의존하고 있다 (DIP 위반)

✓ 따라서 다른 구현체로 변경해야 하는 경우 

해당 코드를 변경해야 한다 (OCP 위반)

✓ 해당 클래스의 책임은 비즈니스 로직을 

수행하는 것인데, 구현체까지 결정하고 있다 

(SRP 위반)
✓ 인터페이스에만 의존한다 (DIP)

✓ 따라서 다른 구현체로 변경해야 하는 경우 

해당 코드에 변경사항은 없다 (OCP)

✓ 해당 클래스는 비즈니스 로직만 수행한다
(SRP)
DI Container ??
• 자바 애플리케이션에서 사용하는 객체들을 생성하고 객체들 간의 의존관계 주입 등을 담당
하기 위해 스프링에서 제공하는 클래스
구현
카테고리
• STEP1. 컨테이너에서 AppCon
fi
g 클래스 활용하여 빈 등록하기 

• STEP2. AppCon
fi
g를 통해 주입되는 객체는 싱글톤 객체여야 한다

• STEP3. 만들어진 컨테이너를 기반으로 초간단 애플리케이션 작성
STEP1. 컨테이너에서 AppConfig 클래스 활용하여 빈 등록하기
• 빈으로 등록하기 위해 AppCon
fi
g에 선언한 다양한 메서드의 메서드 이름, 리턴타입, 

실제 구현체를 어떻게 가져오지 ? 

✓	re
fl
ection, 제네릭 활용! 

• 빈을 담아두는 자료구조는 뭐가 좋을까 ? 

✓	빈 이름/클래스 타입 or 클래스 타입 or 빈 이름으로 원하는 객체를 가져올 수 있어야 한다.

✓	2개의 Map을 활용해서 (빈 이름 - 인스턴스) 쌍과 (타입 - 빈 이름 리스트) 쌍 만든다.

✓	두 번째 Map에서 value가 리스트인 이유는 타입이 같은 빈이 여러 개인 경우도 있기 때문에

✓ 결과적으로 타입으로만 조회하는 경우 해당 타입의 빈 이름을 가져와서 그 이름으로 첫 번째 Map에서 

인스턴스를 얻어올 수 있다.

• 컨테이너 클래스의 관계는 어떤식으로 구성 하는게 좋을까 ?

✓ 현재는 빈을 등록하고 조회하는 기능 위주의 컨테이너이지만 다른 기능의 확장성을 고려해서 

Container 인터페이스에 기능별로 인터페이스를 상속한다(현재는 빈 관련 인터페이스만 상속)

✓ 실제 스프링의 ApplicationContext도 아래와 같이 되어있었다.



public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, 

MessageSource, ApplicationEventPublisher, ResourcePatternResolver
STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다
• 수정자(setter)를 통한 의존관계 주입 방식 

✓ public 으로 set메서드를 선언해야 하기 때문에 추후에 실수로라도 변경될 가능성이 있음

✓ 실수로 의존성 주입을 해주지 않으면 런타임시 NPE 발생할 수 있다.

• 생성자를 통한 의존관계 주입 방식 

✓ 인스턴스 변수를
fi
nal로 선언할 수 있기 때문에 객체가 주입되고 나면 불변이다. 

✓ 대부분의 의존관계는 애플리케이션 종료 전까지 불변해야하므로 불변이 보장되어야 한다. 

✓
fi
nal로 선언한 변수에 대해 생성자에서 초기화를 하지 않으면 컴파일 오류가 나기 때문에 

실수할 일이 없다.

✓ 스프링 공식 문서에서도 생성자를 통한 주입방식 권장

(https://docs.spring.io/spring-framework/docs/5.0.3.RELEASE/spring-framework-reference/core.html#beans-setter-injection) 

✓ 따라서 생성자를 통한 의존관계 주입방식으로 결정
STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다
• 싱글톤 객체를 보장하는 방법 : 모든 구현체 클래스에 싱글톤 패턴 적용

✓ boilerplate 코드가 만들어진다. 

✓ 싱글톤 패턴을 적용하면 유연성이 떨어진다(상속 불가 등)

✓ 싱글턴으로 생성되는 객체는 구현체를 내부에 선언하므로 객체간에 결합도가 높아진다.

• 싱글톤 객체를 보장하는 방법 : 템플릿 메서드 패턴 적용 ?

✓ AppCon
fi
g 클래스에 정의된 메서드 이름이 곧 빈 이름이 될 수 있기 때문에 공통된 추상메서드를

갖는 것은 맞지 않다고 생각
<템플릿 메서드 패턴 예시>
STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다
• 싱글톤 객체를 보장하는 방법 : Con
fi
g 클래스들에 공통적으로 적용될 수 있는 부모 클래스 생성

✓ Container가 여러번 생성되더라도 Con
fi
g에 있는 빈은 한 번만 등록될 수 있도록 static 선언 

✓ 멀티스레딩 환경에서의 동시 접근 문제를 방지하기 위해 ConcurrentHashMap 사용 



STEP3. 만들어진 컨테이너를 기반으로 초간단 애플리케이션 작성
CustomerService


(interface)
CustomerRepository


(interface)
PlannerService


(interface)
MyApp
- 회원가입

- 플래너에게 드레스 투어 요청
 ① 회원등록
 ② 드레스 투어 요청
 ③ 해당 회원 스케줄에 

‘드레스 투어’ 추가
MyContainer
CustomerService


Impl
생성
PlannerService


Impl
TemporaryCustomer
Repository
생성 생성
느낀점
• 내부가 어떻게 돌아가는지 꾸준히 관심을 갖자 

• 프레임워크에 녹아있는 원리를 공부하자

• 자바 기초가 중요한 것 같다

• 테스트 코드 작성하자

More Related Content

Similar to My di container

IoC and DI Pattern
IoC and DI PatternIoC and DI Pattern
IoC and DI PatternSangwon Ko
 
Sql 중심 코드 탈피 발표자료
Sql 중심 코드 탈피 발표자료Sql 중심 코드 탈피 발표자료
Sql 중심 코드 탈피 발표자료ssuser776e2d
 
Sql 중심 코드 탈피
Sql 중심 코드 탈피Sql 중심 코드 탈피
Sql 중심 코드 탈피ssuser776e2d
 
Spring Framework - Inversion of Control Container
Spring Framework - Inversion of Control ContainerSpring Framework - Inversion of Control Container
Spring Framework - Inversion of Control ContainerKyung Koo Yoon
 
보다 나은 웹 어플리케이션 설계
보다 나은 웹 어플리케이션 설계보다 나은 웹 어플리케이션 설계
보다 나은 웹 어플리케이션 설계Eb Styles
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)DK Lee
 
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)탑크리에듀(구로디지털단지역3번출구 2분거리)
 
[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계AnselmKim
 
[Spring]오브젝트와 의존관계
[Spring]오브젝트와 의존관계[Spring]오브젝트와 의존관계
[Spring]오브젝트와 의존관계slowstarter
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍Chris Ohk
 
스프링 스터디 1장
스프링 스터디 1장스프링 스터디 1장
스프링 스터디 1장Seongchan Kang
 
10만 라인, 26280시간의 이야기
10만 라인, 26280시간의 이야기10만 라인, 26280시간의 이야기
10만 라인, 26280시간의 이야기Minyoung Jeong
 
Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입승용 윤
 
Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)sung yong jung
 
클린 코드 part2
클린 코드 part2클린 코드 part2
클린 코드 part2Minseok Jang
 
Golang+on+analytics+and+blockchain
Golang+on+analytics+and+blockchainGolang+on+analytics+and+blockchain
Golang+on+analytics+and+blockchainNAVER Engineering
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀승명 양
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
Spring3 발표자료 - 김연수
Spring3 발표자료 - 김연수Spring3 발표자료 - 김연수
Spring3 발표자료 - 김연수Yeon Soo Kim
 

Similar to My di container (20)

2.Spring IoC & DI (ioc container)
2.Spring IoC & DI (ioc container)2.Spring IoC & DI (ioc container)
2.Spring IoC & DI (ioc container)
 
IoC and DI Pattern
IoC and DI PatternIoC and DI Pattern
IoC and DI Pattern
 
Sql 중심 코드 탈피 발표자료
Sql 중심 코드 탈피 발표자료Sql 중심 코드 탈피 발표자료
Sql 중심 코드 탈피 발표자료
 
Sql 중심 코드 탈피
Sql 중심 코드 탈피Sql 중심 코드 탈피
Sql 중심 코드 탈피
 
Spring Framework - Inversion of Control Container
Spring Framework - Inversion of Control ContainerSpring Framework - Inversion of Control Container
Spring Framework - Inversion of Control Container
 
보다 나은 웹 어플리케이션 설계
보다 나은 웹 어플리케이션 설계보다 나은 웹 어플리케이션 설계
보다 나은 웹 어플리케이션 설계
 
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
자바 웹 개발 시작하기 (5주차 : 스프링 프래임워크)
 
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
(자바교육/스프링교육/스프링프레임워크교육/마이바티스교육추천)#2.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)
 
[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계[스프링 스터디 1일차] 오브젝트와 의존관계
[스프링 스터디 1일차] 오브젝트와 의존관계
 
[Spring]오브젝트와 의존관계
[Spring]오브젝트와 의존관계[Spring]오브젝트와 의존관계
[Spring]오브젝트와 의존관계
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
스프링 스터디 1장
스프링 스터디 1장스프링 스터디 1장
스프링 스터디 1장
 
10만 라인, 26280시간의 이야기
10만 라인, 26280시간의 이야기10만 라인, 26280시간의 이야기
10만 라인, 26280시간의 이야기
 
Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입Dagger 2.0 을 활용한 의존성 주입
Dagger 2.0 을 활용한 의존성 주입
 
Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)
 
클린 코드 part2
클린 코드 part2클린 코드 part2
클린 코드 part2
 
Golang+on+analytics+and+blockchain
Golang+on+analytics+and+blockchainGolang+on+analytics+and+blockchain
Golang+on+analytics+and+blockchain
 
NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀NDC 11 자이언트 서버의 비밀
NDC 11 자이언트 서버의 비밀
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
Spring3 발표자료 - 김연수
Spring3 발표자료 - 김연수Spring3 발표자료 - 김연수
Spring3 발표자료 - 김연수
 

My di container

  • 3. 의존성(의존관계) 주입이란 ? • 호출할 객체를 직접 선언하는게 아니라 런타임시 외부에서 주입해주는 것 • 이게 가능한 이유는 구체적인 객체가 아닌 인터페이스에 의존하기 때문에 • 따라서, 객체 간의 의존관계를 정적인 클래스 관계에서는 알 수 없다.
  • 4. 의존성(의존관계) 주입이 필요한 이유 • DIP, SRP, OCP를 지킨 좋은 설계를 가능하게 해준다. ✓ 구체적인 객체에 의존하고 있다 (DIP 위반) ✓ 따라서 다른 구현체로 변경해야 하는 경우 
 해당 코드를 변경해야 한다 (OCP 위반) ✓ 해당 클래스의 책임은 비즈니스 로직을 
 수행하는 것인데, 구현체까지 결정하고 있다 
 (SRP 위반) ✓ 인터페이스에만 의존한다 (DIP) ✓ 따라서 다른 구현체로 변경해야 하는 경우 
 해당 코드에 변경사항은 없다 (OCP) ✓ 해당 클래스는 비즈니스 로직만 수행한다 (SRP)
  • 5. DI Container ?? • 자바 애플리케이션에서 사용하는 객체들을 생성하고 객체들 간의 의존관계 주입 등을 담당 하기 위해 스프링에서 제공하는 클래스
  • 7. 카테고리 • STEP1. 컨테이너에서 AppCon fi g 클래스 활용하여 빈 등록하기 • STEP2. AppCon fi g를 통해 주입되는 객체는 싱글톤 객체여야 한다 • STEP3. 만들어진 컨테이너를 기반으로 초간단 애플리케이션 작성
  • 8. STEP1. 컨테이너에서 AppConfig 클래스 활용하여 빈 등록하기 • 빈으로 등록하기 위해 AppCon fi g에 선언한 다양한 메서드의 메서드 이름, 리턴타입, 
 실제 구현체를 어떻게 가져오지 ? 
 ✓ re fl ection, 제네릭 활용! • 빈을 담아두는 자료구조는 뭐가 좋을까 ? 
 ✓ 빈 이름/클래스 타입 or 클래스 타입 or 빈 이름으로 원하는 객체를 가져올 수 있어야 한다.
 ✓ 2개의 Map을 활용해서 (빈 이름 - 인스턴스) 쌍과 (타입 - 빈 이름 리스트) 쌍 만든다.
 ✓ 두 번째 Map에서 value가 리스트인 이유는 타입이 같은 빈이 여러 개인 경우도 있기 때문에
 ✓ 결과적으로 타입으로만 조회하는 경우 해당 타입의 빈 이름을 가져와서 그 이름으로 첫 번째 Map에서 
 인스턴스를 얻어올 수 있다. • 컨테이너 클래스의 관계는 어떤식으로 구성 하는게 좋을까 ?
 ✓ 현재는 빈을 등록하고 조회하는 기능 위주의 컨테이너이지만 다른 기능의 확장성을 고려해서 
 Container 인터페이스에 기능별로 인터페이스를 상속한다(현재는 빈 관련 인터페이스만 상속)
 ✓ 실제 스프링의 ApplicationContext도 아래와 같이 되어있었다.
 
 public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, 
 MessageSource, ApplicationEventPublisher, ResourcePatternResolver
  • 9. STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다 • 수정자(setter)를 통한 의존관계 주입 방식 
 ✓ public 으로 set메서드를 선언해야 하기 때문에 추후에 실수로라도 변경될 가능성이 있음
 ✓ 실수로 의존성 주입을 해주지 않으면 런타임시 NPE 발생할 수 있다. • 생성자를 통한 의존관계 주입 방식 
 ✓ 인스턴스 변수를 fi nal로 선언할 수 있기 때문에 객체가 주입되고 나면 불변이다. 
 ✓ 대부분의 의존관계는 애플리케이션 종료 전까지 불변해야하므로 불변이 보장되어야 한다. 
 ✓ fi nal로 선언한 변수에 대해 생성자에서 초기화를 하지 않으면 컴파일 오류가 나기 때문에 
 실수할 일이 없다.
 ✓ 스프링 공식 문서에서도 생성자를 통한 주입방식 권장
 (https://docs.spring.io/spring-framework/docs/5.0.3.RELEASE/spring-framework-reference/core.html#beans-setter-injection) 
 ✓ 따라서 생성자를 통한 의존관계 주입방식으로 결정
  • 10. STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다 • 싱글톤 객체를 보장하는 방법 : 모든 구현체 클래스에 싱글톤 패턴 적용
 ✓ boilerplate 코드가 만들어진다. 
 ✓ 싱글톤 패턴을 적용하면 유연성이 떨어진다(상속 불가 등)
 ✓ 싱글턴으로 생성되는 객체는 구현체를 내부에 선언하므로 객체간에 결합도가 높아진다. • 싱글톤 객체를 보장하는 방법 : 템플릿 메서드 패턴 적용 ?
 ✓ AppCon fi g 클래스에 정의된 메서드 이름이 곧 빈 이름이 될 수 있기 때문에 공통된 추상메서드를
 갖는 것은 맞지 않다고 생각 <템플릿 메서드 패턴 예시>
  • 11. STEP2. AppConfig를 통해 주입되는 객체는 싱글톤 객체여야 한다 • 싱글톤 객체를 보장하는 방법 : Con fi g 클래스들에 공통적으로 적용될 수 있는 부모 클래스 생성
 ✓ Container가 여러번 생성되더라도 Con fi g에 있는 빈은 한 번만 등록될 수 있도록 static 선언 
 ✓ 멀티스레딩 환경에서의 동시 접근 문제를 방지하기 위해 ConcurrentHashMap 사용 
 

  • 12. STEP3. 만들어진 컨테이너를 기반으로 초간단 애플리케이션 작성 CustomerService 
 (interface) CustomerRepository 
 (interface) PlannerService 
 (interface) MyApp - 회원가입 - 플래너에게 드레스 투어 요청  ① 회원등록  ② 드레스 투어 요청  ③ 해당 회원 스케줄에 
 ‘드레스 투어’ 추가 MyContainer CustomerService 
 Impl 생성 PlannerService Impl TemporaryCustomer Repository 생성 생성
  • 13. 느낀점 • 내부가 어떻게 돌아가는지 꾸준히 관심을 갖자 • 프레임워크에 녹아있는 원리를 공부하자 • 자바 기초가 중요한 것 같다 • 테스트 코드 작성하자