Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MVC 구현하기 - 1단계] 주노(최준호) 미션 제출합니다. #346

Merged
merged 7 commits into from
Sep 14, 2023
Merged

Conversation

Choi-JJunho
Copy link
Member

안녕하세요 도치! 🦔
MVC 구현하기 미션을 함께하게되었네요!! 😆

1단계 진행 간 다음과 같은 내용을 구현했습니다.

AnnotationHandlerMapping 구현

AnnotationHandlerMapping은 initialize 수행 시 다음과 같은 흐름으로 동작합니다.

  1. @Controller 어노테이션이 붙은 클래스를 찾아온다.
  2. 클래스에서 @RequestMapping 어노테이션이 붙은 메소드를 찾는다.
  3. 찾은 Method의 annotation 정보를 이용해 HandlerKey 생성
  4. 인스턴스, Method 정보를 이용해 HandlerExecution 생성(클래스 -> 인스턴스 획득)
  5. 해당 정보를 AnnotationHandlerMappinghandlerExecutions Map에 저장
  6. 이후 AnnotationHandlerMapping을 사용하는 측에서는 getHandler() 메소드를 통해 HandlerExecution을 반환 받고 실행

구체적인 구현사항은 코드 내용으로 확인 부탁드립니다 :)

HandlerExecution 구현

public class HandlerExecution {

    private final Object object;
    private final Method method;

    public HandlerExecution(Object object, Method method) {
        this.object = object;
        this.method = method;
    }

    public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
        Object result = method.invoke(object, request, response);
        return (ModelAndView) result;
    }
}

HandlerExecution은 인스턴스와 Method를 필드로 가지며 handle 메소드 수행 시 리플렉션의 invoke 메소드를 통해 Method를 실행하는 역할을 수행합니다.

Copy link

@hum02 hum02 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 주노! 깔끔하게 잘 구현해주셔서 리뷰할 게 많이 없네요..
보고 배웠습니다

@@ -44,6 +44,7 @@ public void await() {
public void stop() {
try {
tomcat.stop();
tomcat.destroy();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼하시네요! 덕분에 stop과 destroy의 차이를 알아갑니다요.
그런데 사용자에 입장에서는 stop()메서드에서 destroy()까지 일어날 거라 예상하지 못할 수 있으니 destroy메서드를 분리할 수도 있겠네요

public void initialize() {
log.info("Initialized AnnotationHandlerMapping!");
Reflections reflections = new Reflections(basePackage);
Set<Class<?>> controllers = reflections.getTypesAnnotatedWith(Controller.class);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reflections를 사용하지 않고 이름을 통해 가져오는 방법도 해보셨었네요!
여담이지만 저는 Object.class를 상속한 class들을 가져오는 방식으로 해보려했으나 안되더군요..
ClassPathScanningCandidateComponentProvider.scanCandidateComponents()를 보니 기존 주노와 비슷하게 fileName으로 찾고있네요


RequestMapping annotation = method.getAnnotation(RequestMapping.class);
for (RequestMethod requestMethod : annotation.method()) {
HandlerKey key = new HandlerKey(annotation.value(), requestMethod);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requestMapping의 값으로 url을 잘 가져와서 등록해주고 계시네요!
혹시 controller의 value로 까지 url prefix를 해주고 싶다면 추가해줄 수도 있을 것 같아요

GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;

public static RequestMethod from(String method) {
return Arrays.stream(values())
Copy link

@hum02 hum02 Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정적 팩토리 메서드까지 잘 사용해주셨습니다. 저는 valueOf()란 메서드를 사용했는데 이렇게 직접 정의하는 게 더 맞는 방식이라 느껴져요

@hum02 hum02 merged commit 7b06d66 into woowacourse:choi-jjunho Sep 14, 2023
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants