Skip to content

Commit

Permalink
feat: 어노테이션 기반 mvc 프레임워크 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
rawfishthelgh committed Sep 13, 2023
1 parent 3345bf4 commit 6de4502
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
package web.org.springframework.web.bind.annotation;

import java.util.Arrays;

public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
GET("GET"),
HEAD("HEAD"),
POST("POST"),
PUT("PUT"),
PATCH("PATCH"),
DELETE("DELETE"),
OPTIONS("OPTIONS"),
TRACE("TRACE");

private final String methodName;

RequestMethod(String methodName) {
this.methodName = methodName;
}

public static RequestMethod from(String methodName) {
return Arrays.stream(values())
.filter(method -> method.methodName.equals(methodName))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 메소드입니다"));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package webmvc.org.springframework.web.servlet.mvc.tobe;

import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.bind.annotation.RequestMapping;
import web.org.springframework.web.bind.annotation.RequestMethod;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class AnnotationHandlerMapping {

Expand All @@ -19,11 +26,29 @@ public AnnotationHandlerMapping(final Object... basePackage) {
this.handlerExecutions = new HashMap<>();
}

public void initialize() {
public void initialize() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Reflections reflections = new Reflections(basePackage);
Set<Class<?>> controllers = reflections.getTypesAnnotatedWith(Controller.class);
for (Class<?> controller : controllers) {
Method[] methods = controller.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(RequestMapping.class)) {
RequestMapping annotation = method.getAnnotation(RequestMapping.class);
String url = annotation.value();
for (RequestMethod requestMethod : annotation.method()) {
Object instance = controller.getDeclaredConstructor().newInstance();
HandlerKey handlerKey = new HandlerKey(url, requestMethod);
HandlerExecution handlerExecution = new HandlerExecution(instance, method);
handlerExecutions.put(handlerKey, handlerExecution);
}
}
}
}
log.info("Initialized AnnotationHandlerMapping!");
}

public Object getHandler(final HttpServletRequest request) {
return null;
HandlerKey handlerKey = new HandlerKey(request.getRequestURI(), RequestMethod.from(request.getMethod()));
return handlerExecutions.get(handlerKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@
import jakarta.servlet.http.HttpServletResponse;
import webmvc.org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Method;

public class HandlerExecution {
private final Object controller;
private final Method method;

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

public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
return null;
return (ModelAndView) method.invoke(controller, request, response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.lang.reflect.InvocationTargetException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand All @@ -14,7 +16,7 @@ class AnnotationHandlerMappingTest {
private AnnotationHandlerMapping handlerMapping;

@BeforeEach
void setUp() {
void setUp() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
handlerMapping = new AnnotationHandlerMapping("samples");
handlerMapping.initialize();
}
Expand Down

0 comments on commit 6de4502

Please sign in to comment.