Skip to content

Commit

Permalink
feat(HandlerMapping) : 핸들러 연결할 수 있도록 로직 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
mjj111 committed May 19, 2024
1 parent d2a55c4 commit e146fb2
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package spring.mvc.handler.mapping;

import jakarta.servlet.http.HttpServletRequest;
import org.reflections.ReflectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spring.mvc.handler.excution.HandlerExecution;
import spring.mvc.annotation.RequestMapping;

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

public class AnnotationHandlerMapping implements HandlerMapping {

private static final Logger log = LoggerFactory.getLogger(AnnotationHandlerMapping.class);
private Object[] basePackage;
private Map<HandlerKey, HandlerExecution> handlerExecutions = new HashMap<>();

public AnnotationHandlerMapping(Object... basePackage) {
this.basePackage = basePackage;
}

public void initialize() {
ControllerScanner controllerScanner = new ControllerScanner(basePackage);
Map<Class<?>, Object> controllers = controllerScanner.getControllers();
Set<Method> methods = getRequestMappingMethods(controllers.keySet());

for (Method method : methods) {
RequestMapping rm = method.getAnnotation(RequestMapping.class);
log.debug("register handlerExecution : url is {}, method is {}", rm.value(), rm.method());
handlerExecutions.put(createHandlerKey(rm),
new HandlerExecution(controllers.get(method.getDeclaringClass()), method));
}

log.info("Initialized AnnotationHandlerMapping!");
}

private HandlerKey createHandlerKey(RequestMapping rm) {
return new HandlerKey(rm.value(), rm.method());
}

@SuppressWarnings("unchecked")
private Set<Method> getRequestMappingMethods(Set<Class<?>> controlleers) {
Set<Method> requestMappingMethods = new HashSet<>();
for (Class<?> clazz : controlleers) {
requestMappingMethods
.addAll(ReflectionUtils.getAllMethods(clazz, ReflectionUtils.withAnnotation(RequestMapping.class)));
}
return requestMappingMethods;
}

@Override
public HandlerExecution getHandler(HttpServletRequest request) {
String requestUri = request.getRequestURI();
RequestMethod rm = RequestMethod.valueOf(request.getMethod().toUpperCase());
log.debug("requestUri : {}, requestMethod : {}", requestUri, rm);
return handlerExecutions.get(new HandlerKey(requestUri, rm));
}
}
31 changes: 31 additions & 0 deletions src/main/java/spring/mvc/handler/mapping/HandlerKey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package spring.mvc.handler.mapping;

import java.util.Objects;

public class HandlerKey {
private String url;
private RequestMethod method;

public HandlerKey(String url, RequestMethod method) {
this.url = url;
this.method = method;
}

@Override
public String toString() {
return "HandlerKey [url= {}" + url + ", requestMethod=" + method + "]";
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HandlerKey that = (HandlerKey) o;
return Objects.equals(url, that.url) && method == that.method;
}

@Override
public int hashCode() {
return Objects.hash(url, method);
}
}
7 changes: 7 additions & 0 deletions src/main/java/spring/mvc/handler/mapping/HandlerMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package spring.mvc.handler.mapping;

import jakarta.servlet.http.HttpServletRequest;

public interface HandlerMapping {
Object getHandler(HttpServletRequest request);
}
5 changes: 5 additions & 0 deletions src/main/java/spring/mvc/handler/mapping/RequestMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package spring.mvc.handler.mapping;

public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

0 comments on commit e146fb2

Please sign in to comment.