티스토리 뷰
Lv3 - 3~4주차 미션 : MVC
https://github.com/woowacourse/jwp-mvc
학습 목표
- @MVC 프레임워크 구현을 통해 MVC 구조와 MVC의 각 역할을 이해한다.
- 새로운 기술을 점진적으로 적용하는 방법을 학습한다.
학습 키워드 (자세한 내용은 강의자료를 다시 보자)
-
웹 서버(WS) vs 웹 어플리케이션 서버(WAS) vs 서블릿 컨테이너의 차이
-
Servlet
- 자바 진영에서 동적인 웹 페이지를 구현하기 위한 표준
- Servlet 표준을 정한 후 interface를 제공
- 각 interface에 대한 구현체는 Servlet Container(Tomcat, Jetty)가 제공
-
이전주차인 WAS 미션때와의 비교
-
Servlet Filter
- 스프링에서의 활용 예시 : HiddenHttpMethodFilter, CharacterEncodingFilter, CorsFilter ...
-
자바 Reflection
요구사항
- Reflection과 관련한 학습 테스트들을 통과시킨다
- 기존엔 WAS미션때처럼 한 컨트롤러에 한 작업단위의 메소드가 존재하며, 이로 인해 이들이 추가될 때마다 URL과 컨트롤러를 매핑하도록 추가해야한다. 이런 ManualHandlerMapping 클래스의 방식을 @RequestMapping을 이용한 AnnotationHandlerMapping 클래스로 바꾼다
- 이때, 리팩토링을 진행하면서 기존의 레거시 코드가 함께 돌아가도록 (처음부터 새로 구현하는 빅뱅전략이 아닌) 점진적인 리팩토링을 한다
- 공통부분을 Interface로 뽑아 추상화해 변경을 최소화
- 기존의 서버는 HTML만 지원하지만 JSON도 지원하도록 수정한다.
- 처음엔 JsonView를 구현했다가, 이후 @ResponseBody와 ViewResolver 추가 구현
추가 미션
- Argument Resolver (Controller 메소드 인자 매핑)
- Interceptor (Servlet Filter 활용)
- Template Engine (JSP외에 handlebars, thymeleaf, freemarker 등 다양한 템플릿을 지원하도록)
느낀점
- 예전에 아무것도 모를때는, 단순히 부트만 써보고 그 편리함에 반해 스프링은 부트가 자동으로 해주는 것들을 일일히 설정해야한다며 마치 원시적이고 귀찮은 기술처럼 보였다. 하지만 이번 MVC미션을 하며 스프링 내부 원리를 '조금은' 알게되며, 지난번 WAS 미션때의 내 코드와 서블릿 등을 생각하면, 스프링도 참 대단하고 내부에서 많은 것들을 처리해주고 있다는 걸 알게 되었다 :)
- DispatcherServlet, HandlerMapping, HandlerAdapter, ViewResolver와 이와 관련된 클래스들에 대해 알게 되었다. Spring MVC의 구조를 조금은 알게 됨
- 실제 현장에선 레거시 코드를 리팩토링하는 일이 많다. 하지만 이때 서비스는 중단되지않고 계속해서 동작해야하기 때문에, 아예 코드를 갈아엎는 빅뱅전략은 쉽지않다. 기존의 코드를 유지하면서 새로운 기능을 추가하는 포비가 항상 강조하는 '점진적인 리팩토링'을 의식적으로 의식하며(?) 연습할 수 있었다.
내 코드, 피드백 관련
- if문 조건문을 supports로, 로직 수행부를 handle 메소드로 갖고있는
HandlerAdapter
인터페이스로 분리할 수 있었다. 굳이 스프링이HandlerAdapter
를 써서라기보다도 이런식으로 인터페이스를 추출하는게 더 좋은것 같음- "실제 if문 제거에 자주 이용되는 방식이라고 한다"
- 역시, 필드로 그냥 넣어버리기 보단 리스트로 관리하는 것이 나중에 적은 변경과 관리하기 좋다
- 이곳에서도 그렇고, Json 관련 구현을 할때 ObjectMapper도 그렇고, 이젠 의식하지않아도 인스턴스 생성이 비효율적이진 않을지 코드를 짜며 습관적으로 생각해봐야한다.
Collection.stream().forEach()
vsCollection.forEach()
- 단순히 코딩센스에 관한 부분. 구현할땐 왜 이 생각을 못했을까
step 2
- 지난주에 접한 Slipp의 예외처리 관련 링크와 예전 토비 스프링의 관련 챕터를 읽은 후로, 감이 안오던 예외처리를 어떻게 해야할지에 대한 부분이 조금씩은 기준이 잡혀가고 있다.
- 해당 예외를 그곳에서 잡는게 맞는지 고민한다
- 추상화수준이 낮은 예외로 던지지말고, 의미를 분명히 포장해 던지는 것이 좋다
- 기본적으론 unChecked가 권장되나, 개발자에게 처리를 강제하고 싶은 부분은 Checked로
- API를 잘 찾아보자 :)
- 기본이 OK다. HttpServletResponse
HandlerMethodReturnValueHandler
- ViewResolver를 구현하며, 스프링의 컨트롤러가 다양한 리턴타입을 어떻게 구별하고 처리해서 지원하는지 궁금해졌다. 이에 대한 부분은 HandlerMethodReturnValueHandler가 담당한다고 한다.
MessageConverter
- 미션 step2의 요구사항은 HTML뿐만 아니라, JSON을 지원하는 것이었고, 이건 JspView처럼 JsonView를 만들어서 처리할 수 있었다.
- 하지만 json타입으로의 response의 데이터처리를 뷰와 동일선상에서 처리한다는게 조금 어색하기도 하다. 실제로도 스프링에선 @ResponseBody를 이용해 컨트롤러가 똑같이 String을 리턴해도 viewName인지 보낼 데이터인지 구분한다.
- "스프링에선 @ResponseBody를 사용했을때, 응답값을 Body에 기록하기로 약속하고 요청 content-type에 따른 MessageConverter를 선택해 알맞은 형태로 기록"한다고 한다.
- 이번 미션에서 나는 MessageConverter까진 아니더라도, @ResponseBody를 구현해 Json을 처리했고, 이 역할은 일단 임시로 나만의 ResponseBodyHandlerAdapter라는 클래스를 만들어 맡겼다.
Pobi 강의 필기, 피드백
- 자바의 표준들
- 인터페이스들을 모아 JDBC 표준으로 정해, 각 DB 벤더들은 JDBC Driver 구현체로 사용한다. 이를 통해, 코드 수정없이 변화를 적용할 수 있다. -> 인터페이스의 장점
- 마찬가지로, Servlet도 표준. 이를 구현체로 사용하며 application 코드의 변경을 최소화할 수 있다.
- JPA는 JDBC를 한단계 더 추상화한 것. Spring MVC도 Servlet이라는 구현체를 사용해 이를 추상화한 것
- MVC 미션부턴 프로젝트가 여러개다. nextstep-mvc 프레임워크를 만들고, application 코드인 slipp 모듈은 계속 바뀌는 부분. study는 학습용 모듈
- 대표적으로 레벨2에서 서비스는 상태가 없기 때문에(메소드만 존재), 인스턴스 하나로 여러 스레드들이 공유하면 효율적이다. 컨트롤러도 가급적 상태를 갖지않도록 하는것이 좋다.
- 컨트롤러에서 서비스 주입받도록, DI로 인스턴스 변수가 생겨도 괜찮은 이유는, DI로 연결된것도 결국 인스턴스가 하나이기 때문. 다만 User 인스턴스 같은걸 DI하면 안좋겠지.
- DI는 A가 사용할 B에 대한 구현체를 외부의 누군가가 결정해준다. 테스트 쉬워진다.
- 리팩토링 과정에서 ManualHandlerMapping에서 인터페이스 추출을 위해 getHandler 메소드의 타입을 약간 수정해야했던(새로운 리팩토링을 위해 기존 레거시 코드를 손대야했던) 찝찝함- 정답은 없다는 답변, 역시 상황에 맞게. 지금은 코드가 복잡하지않고 모든 코드를 컨트롤할수있어서 우리가 약간의 수정을 할 수 있었음.
포비의 MVC 코드와의 비교
- 일급 콜렉션을 포장하라듯이, List<?>를 ~Registry클래스로 포장하니 좀더 깔끔하다
- ControllerScanner는 initialize()에서만 쓰이니까 굳이 인스턴스변수말고 로컬변수로 들고있어도 됬었다..! (실수)
- 내 코드의 initialize()에서 로깅을 위한 두줄은 아직은간단하긴하지만, private 메소드로 감춰도 괜찮았겠다 :)
'우아한 테크코스' 카테고리의 다른 글
우아한 테크코스) Lv3 - 5~6주차 [JDBC 구현, 대용량 데이터 처리] 미션 후기, 코드 리뷰 (0) | 2019.10.20 |
---|---|
우아한 테크코스) Lv3 - 남은 학습주제, 회고 (0) | 2019.10.13 |
우아한 테크코스) Lv1, 2 - 나에 대한 피드백 정리, 회고 (from 미니프로젝트, 페어프로그래밍) (0) | 2019.10.03 |
우아한 테크코스) Lv3 - 1~2주차 [WAS 구현] 미션 후기, 코드 리뷰 (0) | 2019.10.01 |
우아한 테크코스) Lv2 - 남은 학습주제 (0) | 2019.09.17 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- webhacking.kr
- 프로그래머스
- FRAGMENT
- 해외여행
- queue
- 리버싱
- Vo
- Stack
- mysql
- Java
- brute-force
- graph
- OneToMany
- 웹해킹
- JPA
- Android Studio
- 개발자
- Algorithm
- Data Structure
- 우아한 테크코스
- reversing
- socket
- bfs
- Android
- C
- sort
- javascript
- git
- 회고
- dfs
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함