Skip to content

Commit

Permalink
refactor: 메소드 분리 및 로직 개선
Browse files Browse the repository at this point in the history
  • Loading branch information
woosung1223 committed Sep 13, 2023
1 parent da85750 commit 8334363
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
import java.lang.annotation.Annotation;
import java.util.Arrays;

public enum RequestMappings {
public enum CustomRequestMappings {

GET(GetMapping.class),
POST(PostMapping.class),
PUT(PutMapping.class),
DELETE(DeleteMapping.class),
PATCH(PatchMapping.class),
BASIC(RequestMapping.class);
PATCH(PatchMapping.class);

private final Class<?> annotation;

RequestMappings(Class<?> annotation) {
CustomRequestMappings(Class<?> annotation) {
this.annotation = annotation;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package web.org.springframework.web.bind.annotation;

import org.reflections.Reflections;

public class HandlerInstances {

private final Reflections reflections;

public HandlerInstances(Object... basePackage) {
this.reflections = new Reflections(basePackage);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package webmvc.org.springframework.web.servlet.mvc.tobe;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationExtractor {

public static Object extractByMethodName(Annotation annotation, String methodName) {
Class<? extends Annotation> annotationType = annotation.annotationType();
try {
Method method = annotationType.getDeclaredMethod(methodName);
return method.invoke(annotation);
} catch (Exception e) {
e.printStackTrace();
}
throw new RequestMappingPathNotProvidedException();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package webmvc.org.springframework.web.servlet.mvc.tobe;

import static webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationExtractor.*;

import context.org.springframework.stereotype.Controller;
import core.org.springframework.util.ReflectionUtils;
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.RequestMappings;
import web.org.springframework.web.bind.annotation.CustomRequestMappings;
import web.org.springframework.web.bind.annotation.RequestMethod;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
Expand All @@ -32,103 +34,76 @@ public AnnotationHandlerMapping(final Object... basePackage) {
public void initialize() {
log.info("Initialized AnnotationHandlerMapping!");
Reflections reflections = new Reflections(basePackage);
Set<Class<?>> handlerClazzSet = reflections.getTypesAnnotatedWith(Controller.class);
Set<Class<?>> handlerClasses = reflections.getTypesAnnotatedWith(Controller.class);

for (Class<?> handlerClazz : handlerClazzSet) {
addHandlerMappings(handlerClazz);
for (Class<?> handlerClass : handlerClasses) {
addHandlerMappings(handlerClass);
}
}

private void addHandlerMappings(Class<?> clazz) {
Method[] methods = clazz.getDeclaredMethods();
private void addHandlerMappings(Class<?> handlerClass) {
Method[] methods = handlerClass.getDeclaredMethods();

for (Method method : methods) {
Annotation[] annotations = method.getDeclaredAnnotations();
addHandlerMappingIfRequestMappingAnnotationExists(clazz, method, annotations);
addHandlerMappingIfRequestMappingAnnotationExists(handlerClass, method);
}
}

private void addHandlerMappingIfRequestMappingAnnotationExists(Class<?> clazz, Method method, Annotation[] annotations) {
for (Annotation annotation : annotations) {
if (RequestMappings.isAnyMatch(annotation)) {
addHandlerMapping(clazz, method);
}
}
}
private void addHandlerMappingIfRequestMappingAnnotationExists(Class<?> clazz, Method method) {
Annotation[] annotations = method.getDeclaredAnnotations();

private void addHandlerMapping(Class<?> clazz, Method method) {
Annotation requestMappingAnnotation = extractRequestMappingAnnotation(method);
Class<? extends Annotation> annotationType = requestMappingAnnotation.annotationType();
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();

if (annotationType.equals(RequestMapping.class)) {
addWhenAnnotationTypeIsRequestMapping(clazz, method);
return;
if (annotationType.equals(RequestMapping.class)) {
addWhenAnnotationTypeIsRequestMapping(clazz, method);
return;
}
if (CustomRequestMappings.isAnyMatch(annotation)) {
addWhenAnnotationTypeIsCustomRequestMapping(clazz, method);
}
}
addWhenAnnotationTypeIsExtendedRequestMapping(clazz, method);
}

private void addWhenAnnotationTypeIsRequestMapping(Class<?> clazz, Method method) {
Annotation requestMappingAnnotation = extractRequestMappingAnnotation(method);
Annotation requestMappingAnnotation = method.getDeclaredAnnotation(RequestMapping.class);

String requestURI = extractRequestURI(requestMappingAnnotation);
RequestMethod[] requestMethods = extractHttpMethod(requestMappingAnnotation);
String requestURI = (String) extractByMethodName(requestMappingAnnotation, "value");
RequestMethod[] requestMethods = (RequestMethod[]) extractByMethodName(requestMappingAnnotation, "method");

addHandlerExecution(instantiate(clazz), method, requestMethods, requestURI);
}

private void addWhenAnnotationTypeIsExtendedRequestMapping(Class<?> clazz, Method method) {
Annotation requestMappingAnnotation = extractRequestMappingAnnotation(method);
Annotation metaRequestMappingAnnotation = extractMetaRequestMappingAnnotation(requestMappingAnnotation);
private void addWhenAnnotationTypeIsCustomRequestMapping(Class<?> clazz, Method method) {
Annotation customRequestMappingAnnotation = extractCustomRequestMappingAnnotation(method);
Annotation requestMappingAnnotation = extractRequestMappingAnnotation(customRequestMappingAnnotation);

String requestURI = extractRequestURI(requestMappingAnnotation);
RequestMethod[] requestMethods = extractHttpMethod(metaRequestMappingAnnotation);
String requestURI = (String) extractByMethodName(customRequestMappingAnnotation, "value");
RequestMethod[] requestMethods = (RequestMethod[]) extractByMethodName(requestMappingAnnotation, "method");

addHandlerExecution(instantiate(clazz), method, requestMethods, requestURI);
}

private Annotation extractRequestMappingAnnotation(Method method) {
private Annotation extractCustomRequestMappingAnnotation(Method method) {
return Arrays.stream(method.getDeclaredAnnotations())
.filter(RequestMappings::isAnyMatch)
.filter(CustomRequestMappings::isAnyMatch)
.findFirst()
.orElseThrow(RequestMappingNotFoundException::new);
}

private Annotation extractMetaRequestMappingAnnotation(Annotation annotation) {
private Annotation extractRequestMappingAnnotation(Annotation annotation) {
Class<? extends Annotation> annotationType = annotation.annotationType();
Annotation[] metaAnnotations = annotationType.getDeclaredAnnotations();

return Arrays.stream(metaAnnotations)
.filter(metaAnnotation -> metaAnnotation.annotationType().equals(RequestMapping.class))
.findFirst()
.orElseThrow();
}

private static String extractRequestURI(Annotation requestMapping) {
Class<? extends Annotation> annotationType = requestMapping.annotationType();
try {
Method method = annotationType.getDeclaredMethod("value");
return (String) method.invoke(requestMapping);
} catch (Exception e) {
e.printStackTrace();
}
throw new RequestMappingPathNotProvidedException();
}

private static RequestMethod[] extractHttpMethod(Annotation requestMapping) {
Class<? extends Annotation> annotationType = requestMapping.annotationType();
try {
Method method = annotationType.getDeclaredMethod("method");
return (RequestMethod[]) method.invoke(requestMapping);
} catch (Exception e) {
e.printStackTrace();
}
throw new RequestMappingPathNotProvidedException();
.orElseThrow(RequestMappingNotFoundException::new);
}

private Object instantiate(Class<?> clazz) {
try {
Constructor<?> constructor = ReflectionUtils.accessibleConstructor(clazz);
ReflectionUtils.makeAccessible(constructor);
return constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
Expand All @@ -138,6 +113,7 @@ private Object instantiate(Class<?> clazz) {

private void addHandlerExecution(Object clazz, Method method, RequestMethod[] requestMethods, String requestURI) {
HandlerExecution handlerExecution = new HandlerExecution(clazz, method);

for (RequestMethod each : requestMethods) {
HandlerKey handlerKey = new HandlerKey(requestURI, each);
handlerExecutions.put(handlerKey, handlerExecution);
Expand Down

0 comments on commit 8334363

Please sign in to comment.