목차
초창기 Spring URI 매핑
1. Java 언어 수준의 제약
- Spring 2.x 이전은 어노테이션 기반 프로그래밍이 제한적이었습니다.
- 당시에는 `@Controller`, `@RequestMapping`같은 어노테이션 기반 선언이 없거나 미지원이 많았습니다.
- 따라서 개발자는 구현체 등록 + 이름 매핑 방식을 사용해서 컨트롤러를 연결했습니다.
예시 코드
@Component("/example-controller")
public class ExampleController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String method = request.getMethod();
if ("GET".equalsIgnoreCase(method)) {
System.out.println("GET 요청 처리");
}
return null;
}
}
1. 요청
웹 브라우저나 클라이언트에서 `/example-controller`로 요청이 들어옵니다.
GET /example-controller
- HttpServletRequest 객체에서 Http Method를 확인하여, 조건을 나누었습니다.
2. DispatcherServlet
Spring은 프론트 컨트롤러인 `DispatcherServlet`이 모든 HTTP 요청을 받아 처리합니다.
DispatcherServlet
↓
HandlerMapping
↓
Controller
3. HandlerMapping이 Controller 탐색
`DispatcherServlet`은 등록된 `HandlerMapping`을 이용해 요청 URI에 해당하는 컨트롤러를 찾습니다.
- `@Component("/example-controller")`처럼 이름을 명시하여 Bean을 등록하면, `BeanNameUrlHandlerMapping(구현체)`은 해당 이름(/example-controller)과 일치하는 URI 요청을 해당 Bean으로 매핑합니다. `DispacherServlet`은 Handler 객체(Controller)에 맞는 `HandlerAdapter`를 통해 `handleRequest()`를 실행합니다. (이름 매핑 방식)
4. Controller 호출
찾은 컨트롤러의 `handleRequest()` 메서드를 호출합니다
if ("GET".equalsIgnoreCase(method)) {
System.out.println("GET 요청 처리");
}
return null;
- `GET` 요청인 경우, 출력이 콘솔에 나오면, Spring이 해당 요청을 `ExampleController`에 잘 연결한 것입니다.
현재 어노테이션 기반 Spring URI 매핑
과거처럼 `Controller` 인터페이스와 `handleRequest()`를 사용하지 않고, Java 5 이후 도입된 어노테이션을 사용하여 URL과 메서드를 직관적으로 매핑합니다.
예시 코드
@Controller
@RequestMapping("/example")
public class ExampleController {
@GetMapping("/hello")
public String hello() {
return "helloView";
}
}
1. 메서드 단위로 매핑 테이블 생성
애플리케이션 실행 시, `@Controller`, `@RequestMapping`이 있는 클래스들을 검사한 후 다음과 같이 매핑을 기억합니다.
GET /example/hello → ExampleController.hello()
2. 요청
웹 브라우저나 클라이언트에서 `/example/hello`로 GET 요청이 들어옵니다.
GET /example/hello
3. DispatcherServlet
Spring은 프론트 컨트롤러인 `DispatcherServlet`이 모든 HTTP 요청을 받아 처리합니다.
DispatcherServlet
↓
HandlerMapping (인터페이스)
↓
RequestMappingHandlerMapping (핸들러 찾음)
↓
HandlerMethod 반환
4. HandlerMapping을 통해 컨트롤러 메서드(Handler) 찾기
- `DispatcherServlet`이 요청을 받으면, 등록된 `HandlerMapping(인터페이스)`을 통해 해당 URL과 HTTP method에 매칭되는 `HandlerMethod`를 찾습니다.
- `RequestMappingHandlerMapping(구현체)`이 URL("/example/hello"), HTTP method를 보고 매핑된 컨트롤러 메서드(`HandlerMethod`) 클래스를 반환합니다. (컨트롤러 객체 + 메서드 정보)
HandlerMethod 예
HandlerMethod {
bean: ExampleController
method: hello() // 리플렉션으로 호출될 대상
...
}
- `HandlerMethod`는 실제 컨트롤러 객체와 실행할 메서드 정보를 가지고 있으며, Spring은 리플렉션을 사용하여 이 메서드를 실행합니다. 이는 예전의 `handleRequest()`처럼 단일 진입점이 아니라, 다양한 메서드로 요청을 나눌 수 있게 해줍니다.
차이점
항목 | 초창기 Spring | 현재 Spring |
컨트롤러 선언 방식 | `Controller` 인터페이스 구현 | `@Controller` 어노테이션 사용 |
요청 처리 메서드 | `handleRequest(HttpServletRequest, HttpServletResponse)` | `@GetMapping`, `@PostMapping` 등 어노테이션으로 메서드 직접 매핑 |
URI 매핑 방식 | Bean 이름 기반 매핑 (`@Component("/url")`) | `@RequestMapping`, `@GetMapping` 등으로 URL 및 메서드 매핑 |
HandlerMapping 구현체 | `BeanNameUrlHandlerMapping` | `RequestMappingHandlerMapping` |
핸들러 호출 방식 | `Controller`의 `handleRequest()` 메서드 호출 | `HandlerMethod`를 통해 리플렉션으로 특정 메서드 실행 |
요청 구분 방식 | `HttpServletRequest.getMethod()`로 직접 분기 | `@GetMapping`, `@PostMapping` 등으로 자동 구분 |
유연성 및 유지보수성 | 낮음 (URL과 메서드가 하드코딩됨) | 높음 (어노테이션으로 명확한 구조 제공) |
지원 HTTP 메서드별 처리 | 수동 if-else 처리 | 메서드별 어노테이션 사용 (`@GetMapping`, `@PostMapping` 등) |
핸들러 정보 표현 | 컨트롤러 Bean 하나만 반환 | `HandlerMethod` 객체에 Bean + Method 정보를 포함하여 반환 |
코드 가독성 | 낮음 (로직 분기가 코드 안에 직접 존재) | 높음 (매핑이 명시적이고 구조화됨) |
'Spring' 카테고리의 다른 글
[Spring] Spring MVC, RequestMappingHandlerAdapter의 요청 및 응답 처리 과정 : ArgumentResolver & ReturnValueHandler란? (0) | 2025.06.05 |
---|---|
[Spring] Spring MVC, RequestMappingHandlerAdapter의 요청 및 응답 처리 과정 (0) | 2025.06.05 |
[Spring] 의존 관계 주입 방법 4가지 (2) | 2025.05.23 |
[Spring] Bean 등록 방법 (4) | 2025.05.23 |
[Spring] Spring Bean 어떻게 등록될까? (0) | 2025.05.23 |