일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ZuulFilter
- dp
- spring cloud
- 유레카
- 달팽이
- 게이트웨이
- 메모이제이션
- 구간 트리
- 플로이드 와샬
- BFS
- 이분 탐색
- 백트래킹
- 주울
- 구현
- docker-compose
- 도커
- Java
- Logback
- 서비스 디스커버리
- 다익스트라
- Spring Cloud Config
- 트리
- Zuul
- 비트마스킹
- 스프링 시큐리티
- spring boot
- 완전 탐색
- 스택
- Gradle
- 이분 매칭
- Today
- Total
Hello, Freakin world!
dispatch 기능 구현하기 본문
public Response dispatch(Request request) {
Method[] methods = RequestHandler.class.getMethods();
Optional<Method> handlerOpt = findHandler(methods, request.getUrl(), request.getMethod());
try {
Method handler = handlerOpt.orElseThrow(() ->
new NotFoundException("url 에 해당하는 핸들러를 찾지 못했습니다."));
return invoke(requestHandler ,handler, request);;
} catch (NotFoundException e) {
e.printStackTrace();
return new Response(404, "not found handler");
}
}
코드의 뼈대는 다음과 같다.
dispatch의 인수로 지정된 Request를 이용해 클라이언트의 요청 정보를 받고,
요청 정보를 이용해 RequestHandler에 포함된 핸들러에 매핑한다.
findHandler 메서드는 reflection과 Stream api을 이용해 RequestHandler에 등록된 메서드 중
요청 정보를 만족하는 메서드가 있는지 탐색한다.
이는 Optional<Method>를 반환하고, 만족하는 메서드가 없는 경우 404 Not Found 예외를 던지도록 해주자.
아래는 findHandler 코드다.
private Optional<Method> findHandler(Method[] methods, String url, io.request.Method protocolMethod) {
return Arrays.stream(methods)
.filter(method -> method.isAnnotationPresent(RequestMapping.class))
.filter(method -> method.getAnnotation(RequestMapping.class).method().equals(protocolMethod))
.filter(method -> URLParser.validateUrl(method.getAnnotation(RequestMapping.class).url(), url))
.findFirst();
}
애너테이션을 이용한 프레임워크를 구성하는데 있어, findHandler 메서드는 핵심적인 역할을 한다.
살짝만 RequestHandler 클래스를 엿보고 오자.
public class RequestHandler {
...
@RequestMapping(method = Method.GET, url = "/rooms")
public Response getRooms(Request request) {
...
return new Response(200, "success", responseBody);
}
...
}
@RequestMapping 이라는 애너테이션의 속성에 식별 정보를 미리 지정하고 있다.
findHandler 메서드는 reflection api를 이용해 메서드에 마크된 애너테이션의 타입이 원하는 타입인지 확인하고,
Method(GET,POST 등의 값을 가지는 enum 클래스) 와 url 을 비교하고 있다.
이로서 다소 엉성하지만 그럴듯한 프레임워크가 완성됐다.
이렇게 dispatch 하는 기능이 없다면, 아마도 controller에서 if문을 이용해 핸들러를 분기하게 될 것이다.
이 방법은 갈수록 유지보수하기도 힘들고, 가독성도 떨어진다. 그리고 결국 클래스 간의 강결합을 유발하는 요인이 된다.
하지만 이 방식에서는 컨트롤러는 핸들러 정보에 대해서 전혀 몰라도 된다.
새로운 핸들러는 RequestHandler에만 추가하면 끝!
마지막으로 찾은 메서드를 invoke 하는 과정이 필요한데,
이는 추가하려는 기능과 연관되는 부분이 있어 다시 살펴보도록 하자.
'Toy Project > URL Mapping 프레임워크 구현하기' 카테고리의 다른 글
단위 테스트의 작성 그리고 완성! (0) | 2020.04.02 |
---|---|
기능 추가 - URL에 포함된 정보를 자동으로 메서드 인수에 바인딩하기 (0) | 2020.04.01 |
Spring @RequestMapping과 같은 URL 매핑 프레임워크 구현하기 (0) | 2020.03.31 |