티스토리 뷰
Lv3 - 7~9주차 미션 : DI 구현
https://github.com/woowacourse/jwp-di
학습목표
- DI 프레임워크 구현을 통해 DI 개념과 Spring 프레임워크 이해
- AOP 개념 및 Spring AOP 적용
- Transaction과 Spring Transaction
요구사항
step1
- BeanFactory, BeanScanner 구현
- 이전의 MVC 미션 코드까진, 자바 Reflection을 활용해
@Controller
를 찾아 인스턴스를 생성하고 URL 매핑을 자동화했다. 같은 방법으로@Service
,@Repository
도 각 클래스에 대한 인스턴스 생성과 의존관계 설정을 어노테이션으로 자동화한다. - 각 인스턴스간의 의존관계는
@Inject
어노테이션 사용 - MVC모듈의 ControllerScanner를 DI모듈로 이동하고,
@Controller, @Service, @Repository
에 대한 지원이 가능하도록 개선해 BeanScanner로 개선 - MVC모듈의 AnnotationHandlerMapping이 BeanFactory와 BeanScanner를 활용해 동작하도록 리팩토링
- 이전의 MVC 미션 코드까진, 자바 Reflection을 활용해
step2
@Configuration
,@ComponentScan
,@Bean
설정@Configuration
을 이용해 설정파일을 등록할 수 있도록 구현한다.- step1에서 classPath를 스캔해 등록된 빈들과
@Configuration
을 통해 등록된 빈들간에도 di되도록 한다.
느낀점
- 역시 대망의 레벨3 마지막 미션답게 우테코 미션들 중 가장 어려운 난이도였다. 다만 그만큼 중요한만큼, 이번 미션외에 실제 스프링의 DI구조에 대해 나중에 제대로 파봐야할 필요성을 느낀다. 미션과정에서 자료들을 읽으며 복잡해서 아직 다 따라가며 이해하진 못했다.
- step1까진 나름 괜찮았으나, step2부터 멘붕이 왔다. step2를 기능구현만 시키려면 어떻게든 했겠으나, step1-2를 통합시켜 이쁘게 짜려니 처음에 마땅한 방법이 떠오르지 않았다.
- 결국 가장 어려웠던 건, step1의 classPath를 스캔하며 빈을 등록하는 방식과 step2의 configuration을 통해 빈을 등록하는 방식을 일관된 구조로 작동하도록 통합시키는 것이었다.
- 이 과정에서, MVC 미션에서 해봤던 '점진적인 리팩토링'이 도움됬다. 기존의 구조와 비슷한 구조로 일단은 별개의 클래스로 구현, 둘 간의 공통부분을 찾고 (대표적으로 interface 등을 이용) 추출해 통합, 하나씩 새로운 구조로 바꿔가며 레거시가 더이상 쓰이지 않으면 삭제.
- 초반에 미션 요구사항과 내가 구현하려고하는 목표가 무엇인지 '정확하게' 이해하지않은채로, 구현을 진행하려했다. 때문에 시간이 좀더 많이 소요됬던것같고 그러지 않아야겠단 아쉬움이 조금 있다.
내 코드, 피드백 관련
핵심
- BeanFactory#createBean의 재귀를 이용한 Bean 생성 로직 구조 (결국 arguments들을 준비하고 생성)
- 결국엔 생성자/메소드 두 방식으로 다르게 인스턴스화된다는 사실 : 기본적으로 ClasspathBeanScanner-ConstructorBeanDefinition, ConfigurationBeanScanner-MethodBeanDefinition으로 매핑되던 구조
Step 1
- Step1땐 BeanFactory와 BeanScanner의 의존관계를 어떻게 맺어야할지, 어디에 위치해야할지를 고민했다. Step2를 진행하며 둘의 관계가 점점 복잡해졌는데, 이 부분은 마지막에 ApplicationContext까지 구현하다보니 감춰지며 무척 깔끔해질수있었다.
- stream에서 collect(toMap(~))도 나름 쓸만하더라
- 배열보단 리스트 - 너무 습관으로 굳어져버렸다. 이 경우엔 로직의 시작과 끝이 array라 그냥 배열로 구현해도 됬었음 :)
Step 2
- BeanDefinition
- 2가지 방식의 BeanDefinition을 정의하고 구현했던 것이 가장 핵심이자 관건이었다. 이를 통해 BeanDefinition 인터페이스로 BeanFactory에서 통합시킬수있었다.
- 세부적인건 최대한 BeanFactory에서 분리해 각 BeanDefinition들쪽으로 넣으려했고, 그나마 이정도가 최선이었다.
- BeanFactory
- 초반 각자 다르게 구현한 상태인 ClasspathBeanFactory와 ConfigurationBeanFactory를 합치는게 가장 어렵고 방법이 떠오르지않아 시간이 오래 걸렸다.
- 결과적으로 위의 BeanDefinition들을 만들어서 통합시킬수있었다.
- createBean()도 구현하고보니 맨처음 ClasspathBeanFactory의 해당로직과 거의 비슷하더라.
- BeanScanner
- 오랜만에 stream 쓰니 재밌었다.
- ConfigurationBeanScanner의 생성자 인자는 여러 방식을 지원하면 좋을것같아 두가지가 만들어놓았다.
- ApplicationContext
- BeanFactory와 BeanScanner 사이의 관계를 담당시킬수있었다. 덕분에 사용하는 쪽에서 코드가 훨씬 간결해지고 내부사정을 몰라도 되게 되었다. 사실 이게 없었다면, BeanFactory와 BeanScanner 사이를 잘못연결하면 터지는 거니까.
- 지금은 사용하는 쪽이 간단해서 getBeanFactory()만 만들어두었는데, 나중을 생각하면 주요 메서드들을 bypass 메서드로 만들어뒀어도 좋았을거같단 생각. -> 역시, 피드백으로 와서 ApplicationContext가 담당할수있도록 bypass메서드 추가!
읽어봤던 자료들
'우아한 테크코스' 카테고리의 다른 글
우아한 테크코스) Lv4 [팀 프로젝트] 정리, 후기 (0) | 2020.01.09 |
---|---|
우아한 테크코스) Lv3 - 5~6주차 [JDBC 구현, 대용량 데이터 처리] 미션 후기, 코드 리뷰 (0) | 2019.10.20 |
우아한 테크코스) Lv3 - 남은 학습주제, 회고 (0) | 2019.10.13 |
우아한 테크코스) Lv3 - 3~4주차 [MVC 구현] 미션 후기, 코드 리뷰 (0) | 2019.10.13 |
우아한 테크코스) Lv1, 2 - 나에 대한 피드백 정리, 회고 (from 미니프로젝트, 페어프로그래밍) (0) | 2019.10.03 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 개발자
- C
- mysql
- 프로그래머스
- bfs
- Android
- 웹해킹
- webhacking.kr
- brute-force
- sort
- 리버싱
- FRAGMENT
- 해외여행
- javascript
- reversing
- JPA
- socket
- 회고
- Vo
- Stack
- Java
- 우아한 테크코스
- git
- queue
- Algorithm
- dfs
- graph
- Android Studio
- OneToMany
- Data Structure
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함