Next JWP Study 08
2017.05.01
MVC 프레임워크 3단계 실습
여덟 번째 수업 이모저모
- 수업은
2017-04-27 19:00:00 +0900
에 시작. - 오늘은 Reflection 연습을 하고, annotation 기반의 MVC Framework를 만들어 본다.
- Reflection에 익숙한 사람은 Framework 만들기로 바로 들어가기로 한다.
- 나는 Reflection에 익숙한 편이라고 스스로 판단하고 Framework 만들기로 바로 들어갔다.
단상 : 삶과 프로그래밍
- 몰입
- 몰입은 단순히 작업 능률에만 영향을 주는 것이 아니라, 삶과 행복과도 관련이 있다.
- 그렇다면 어떻게 몰입할 것인가?
Reflection
나는 Java로 코드를 작성할 때 Reflection을 즐겨 쓰는 편이지만 Reflection을 썩 좋아하지는 않는다. Reflection을 써서 코딩하고 있다 보면 Java의 아이덴티티가 희석되는 느낌이 들기 때문이다.
나는 Java 문법상의 한계가 Reflection에서 드러난다고 생각한다. 그리고 Reflection이 Java의 장점에 해를 끼친다고 본다.
나는 딱히 자신 있는 언어가 없고, Java에 대해서도 아직 초심자에 속한다고 생각한다. 정적 타입 언어보다는 동적 타입 언어가 더 성격에 맞는 편이다. 그럼에도 불구하고 뭔가 새로운 것을 만들 때, 나는 Java를 항상 중요한 선택지 중의 하나로 고려한다. 왜냐하면 Java는 컴파일 타임에서 꽤 많은 실수를 걸러낼 수 있기 때문이다. 그게 가능하기 때문에 Java IDE의 신뢰할 수 있는 대규모 리팩토링이나 스마트한 자동완성도 가능하다.
그런데 Reflection을 적극적으로 사용하게 되면 컴파일 타임에서 얻을 수 있는 이득을 상당부분 포기해야 한다. 내 기준으로 Java를 선택할 중요한 이유가 사라지는 셈이다.
하지만 그럼에도 불구하고 Java는 현대 산업에 있어 중요한 언어이고 그러한 Java의 한계를 극복하게 해 주는 Reflection은 주요 프레임워크들에 의해 널리 사용되고 있다. 물론 Reflection이 제한 없이 사용되는 건 아닌 모양이다. Reflection은 프로그램 가동시에만 사용하고, 가능한 한 검증된 라이브러리에 수록된 것만 사용해야 한다는 암묵적인 원칙이 공유되고 있는 느낌이다.
폴 그레이엄이 Java를 두고 실수 예방에 초점을 맞춘 언어라고 했던 게 생각난다. 폴 그레이엄은 Java를 까면서 그런 말을 했지만, 사실 Java는 실수 예방에 굉장히 뛰어난 언어이기 때문에 주류 언어가 되었고 앞으로도 꽤 오랫동안 산업계에서 사랑받을 거라고 생각한다.
그러고보니 래리 월은 Java가 좋은 의미의 현대판 Cobol이라 했었던 것 같다.
(어느 문서에서 말했는지는 잘 기억이 안 나는데 링크를 찾아다 붙여놓을 예정이다)
MVC Framework 구현
- 구현 내용은 GitHub Repository에 올려두었다.
- Reflection을 사용해서
@Controller
어노테이션과@RequestMapping
어노테이션을 수집하고, 그에 따라 요청을 처리하도록 수정하였다. 아래는UserController.java
의 내용을 축약한 것이다.
@Controller("/users")
public class UserController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
private UserDao userDao = UserDao.getInstance();
@RequestMapping("")
public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 생략
}
@RequestMapping("/form")
public ModelAndView form(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 생략
}
@RequestMapping(value = "/create", method = RequestMethod.POST)
public ModelAndView create(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 생략
}
@RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(HttpServletRequest req, HttpServletResponse response) throws Exception {
// 생략
}
@RequestMapping("/updateForm")
public ModelAndView updateForm(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 생략
}
@RequestMapping("/profile")
public ModelAndView profile(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 생략
}
}
- url에 중복이 많아서
Controller
에 prefix를 지정할 수 있도록 작업해 봤다. - 하나하나의 메서드가 각각의 Request를 담당하게 되니 여러 Controller 클래스를 하나로 합칠 수 있었다.
- 이정도면 일단 만족. Spring이랑 비슷한 모양이 나오네.
- 아,
DispatcherServlet
은 다음과 같은 모양을 갖추게 되었다.
@WebServlet(name = "dispatcher", urlPatterns = "/", loadOnStartup = 1)
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(DispatcherServlet.class);
private ControllerMapping controllerMap;
@Override
public void init() throws ServletException {
controllerMap = new ControllerMapping(core.annotation.Controller.class, "next.controller");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String requestUri = req.getRequestURI();
logger.debug("Method : {}, Request URI : {}", req.getMethod(), requestUri);
final ControllerData controllerData = controllerMap.get(req.getMethod(), req.getRequestURI());
final ModelAndView mav = controllerData.execute(req, resp);
final View view = mav.getView();
try {
view.render(mav.getModel(), req, resp);
} catch (Exception e) {
logger.error("Exception : {}", e);
throw new ServletException(e.getMessage());
}
return;
}
}
Links
- step8 과제 완료
- JournalDev : Java Heap Space vs Stack – Memory Allocation in Java
- Paul Graham : Java's Cover
- Paul Graham : Java's Cover(한국어)
- 폴 그레이엄은 Java를 매우 까는 입장인데, Java를 사랑하는 사람이라면 이 글을 읽기 전에 심호흡을 하고, 그가 엄청나게 하드코어한 Lisp 해커라는 점을 염두에 두길 바란다.
- Larry Wall : 5 Programming Languages Everyone Should Know
- 수업 자료
링크를 찾아 일일이 달아놓는 건 꽤 귀찮은 일이지만, 한편으로는 꽤 재미있는 일이기도 하다.