์๋ก
Spring MVC๊ฐ ๋์ํ๋ ๊ณผ์ ์ค, DispatcherServlet์ด ์ปจํธ๋กค๋ฌ์ ์ ๊ทผํ๋ ๊ณผ์ ์ ์์ธํ๊ฒ ์ค๋ช ํ๋ ค๊ณ ํ๋ค.
HandlerMapping
์๋น์ผ๋ก ์์๋ฅผ ๋ค์ด๋ณด์. ์๋์ ๋ค์ด์์ ๋ค์ํ ์ฃผ๋ฌธ์ ํ๊ณ ํด๋น ์ฃผ๋ฌธ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํ ์์คํ ์ ๋ง๋ค์๋ค.
- ์ฃผ๋ฌธ ์ ์์ (HandlerMapping)
- ์ ๋ฌธ ์๋ฆฌ์ฌ (์ปจํธ๋กค๋ฌ/ํธ๋ค๋ฌ)
HandlerMapping (์ฃผ๋ฌธ ์ ์์)
- ์ญํ : "์ด๋ค ์๋(์์ฒญ)์ ์ฃผ๋ฌธ(URL)์ด ์ด๋ค ์๋ฆฌ์ฌ(์ปจํธ๋กค๋ฌ)์๊ฒ ๊ฐ์ผ ํ ์ง"๋ฅผ ๊ฒฐ์ ํ๊ณ ์ฐ๊ฒฐํด ์ค๋ค.
- ์ค๋ช : "์คํ ์ดํฌ" ์ฃผ๋ฌธ์ '์คํ ์ดํฌ ์ ๋ฌธ ์๋ฆฌ์ฌ'์๊ฒ, "ํ์คํ" ์ฃผ๋ฌธ์ 'ํ์คํ ์ ๋ฌธ ์๋ฆฌ์ฌ'์๊ฒ ์ ๋ฌํด์ผ ํจ์ ์ฃผ๋ฌธ ์ ์์(HandlerMapping) ์ด ํ์ ํ๊ณ ์ฐ๊ฒฐํ๋ค.
==> HandlerMapping์ ๋ค์ด์ค๋ ์น ์์ฒญ(URL)์ ๋ณด๊ณ , ์ด ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ์ปจํธ๋กค๋ฌ(Controller)๋ฅผ ์ฐพ์์ค๋ค.
// ์ด ๋งคํ์ @Controller ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค์ @RequestMapping ์ด๋
ธํ
์ด์
์ด ๋ถ์ ๋ฉ์๋๋ฅผ ์ค์บํ์ฌ
// ํน์ URL ์์ฒญ์ด ์์ ๋ ์ด๋ค ์ปจํธ๋กค๋ฌ์ ์ด๋ค ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ ์ง ๊ฒฐ์ ํ๋ค
@Controller
public class OrderController {
@GetMapping("/order/steak") // ์ด URL ์์ฒญ์ด ์ค๋ฉด
public String orderSteak() { // ์ด ๋ฉ์๋๊ฐ ์คํ๋์ด์ผ ํ๋ค๊ณ HandlerMapping์ด ํ์
ํ๋ค
return "steakOrderPage";
}
@GetMapping("/order/pasta") // ์ด URL ์์ฒญ์ด ์ค๋ฉด
public String orderPasta() { // ์ด ๋ฉ์๋๊ฐ ์คํ๋์ด์ผ ํ๋ค๊ณ HandlerMapping์ด ํ์
ํ๋ค
return "pastaOrderPage";
}
}
// ์ ์ฝ๋์์ /order/steak๋ผ๋ ์์ฒญ์ด ์ค๋ฉด
// OrderController์ orderSteak() ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํ๋ค๊ณ HandlerMapping์ด ์๋ ค์ค๋ค
HandlerMapping์ ๋์ ์๋ฆฌ
DispatcherServlet์ ์์ฒญ์ ๋ฐ์ผ๋ฉด, HandlerMapping์๊ฒ ์์ฒญ์ ์์ํ์ฌ ํด๋น ์์ฒญ์ ์ฒ๋ฆฌํ ํธ๋ค๋ฌ๋ฅผ ์ฐพ๋ ๊ฒ์ ๊ฐ์ฅ ๋จผ์ ์์ํ๋ค.
1. HanlerMapping ์กฐํ
DispatcherServlet์ ์ค์ ๋ HandlerMapping ๋น๋ค์ ์ํํ๋ฉฐ ์์ฒญ์ ์ฒ๋ฆฌํ Handler๋ฅผ ์ฐพ์๋ฌ๋ผ๊ณ ์์ฒญ. ์ฐ์ ์์(Order)์ ๋ฐ๋ผ ์กฐํ
2. Handler ๊ฒ์
๊ฐ HandlerMapping ๊ตฌํ์ฒด๋ ์์ ๋ง์ ๋งคํ ์ ๋ต์ ๋ฐ๋ผ ์์ฒญ URL๊ณผ ๋งคํ๋๋ ํธ๋ค๋ฌ๋ฅผ ์ฐพ๋๋ค.
ex: @RequestMapping ์ด๋ ธํ ์ด์ ๊ธฐ๋ฐ HandlerMapping์ ํด๋์ค, ๋ฉ์๋์ ๋ถ์ @RequestMapping ์ ๋ณด๋ฅผ ๋ถ์ ํ ๋งคํ
3. HandlerExecutionChain ๋ฐํ
HandlerMapping์ด ์์ฒญ์ ํด๋นํ๋ ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ผ๋ฉด, ๋จ์ํ ํธ๋ค๋ฌ ๊ฐ์ฒด๋ง ๋ฐํํ๋ ๊ฒ์ด ์๋๋ผ HandlerExecutionChain ๊ฐ์ฒด ๋ฐํ -> HandlerExecutionChain์ ๋ค์๊ณผ ๊ฐ์ ์ ๋ณด๊ฐ ํฌํจ๋๋ค.
- Handler ๊ฐ์ฒด: ์ค์ ์์ฒญ์ ์ฒ๋ฆฌํ ์ปจํธ๋กค๋ฌ์ ๋ฉ์๋ (๋๋ ํด๋น ๋ฉ์๋๋ฅผ ๊ฐ์ธ๋ ํ๋ก์ ๊ฐ์ฒด)
- Interceptor ๋ชฉ๋ก: ํด๋น ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ ์, ํ์, ๊ทธ๋ฆฌ๊ณ ์๋ฃ ํ์ ์คํ๋ HandlerInterceptor(์ธํฐ์ ํฐ)๋ค์ ๋ชฉ๋ก
4. HandlerAdapter ์ ํ (by DispatcherServlet)
DispatcherServlet์ HandlerExecutionChain์์ ์ป์ Handler ๊ฐ์ฒด๋ฅผ ์ค์ ๋ก ์คํํ HandlerAdapter๋ฅผ ์ฐพ๋๋ค. Handler๋ ๋ค์ํ ํํ์ผ ์ ์์ผ๋ฏ๋ก, HandlerAdapter๋ ํธ๋ค๋ฌ์ ์ข ๋ฅ์ ๋ฐ๋ผ ์ ์ ํ ๋ฐฉ์์ผ๋ก ํธ๋ค๋ฌ๋ฅผ ํธ์ถํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
5. Handler ์คํ
์ ํ๋ HandlerAdapter๊ฐ HandlerExecutionChain์ ์๋ Handler ๊ฐ์ฒด๋ฅผ ํธ์ถํ์ฌ ์์ฒญ์ ์ฒ๋ฆฌ
์ฃผ์ HandlerMapping ๊ตฌํ์ฒด
- ์คํ๋ง์ ๋ค์ํ HandlerMapping ๊ตฌํ์ฒด๋ฅผ ์ ๊ณตํ๋ฉฐ, ๊ฐ๋ฐ์๋ ํ์์ ๋ฐ๋ผ ์ด๋ฅผ ์กฐํฉํ์ฌ ์ฌ์ฉ
- ์คํ๋ง ๋ถํธ๋ฅผ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ ๋ช ์์ ์ผ๋ก ์ค์ ํด์ผ ํ์ง๋ง, ์คํ๋ง ๋ถํธ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ง์ด ์ฌ์ฉ๋๋ HandlerMapping๋ค์ ์๋์ผ๋ก ๋ฑ๋ก
RequestMappingHandlerMapping
- ํน์ง: ์คํ๋ง 3.1๋ถํฐ ๋์ ๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ HandlerMapping์ผ๋ก, @Controller ๋ฐ @RestController ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค์ @RequestMapping, @GetMapping, @PostMapping ๋ฑ ์์ฒญ ๋งคํ ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋๋ฅผ ์ค์บํ์ฌ ๋งคํ ์ ๋ณด๋ฅผ ๊ตฌ์ฑํ๋ค.
- ๋์: ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ ๋ชจ๋ ์ปจํธ๋กค๋ฌ ํด๋์ค๋ฅผ ์ค์บํ์ฌ @RequestMapping ์ด๋ ธํ ์ด์ ์ด ์๋ ๋ฉ์๋๋ค์ ์ฐพ๊ณ , ํด๋น ๋ฉ์๋์ ๋งคํ๋ URL ํจํด ์ ๋ณด๋ฅผ ๋ด๋ถ์ ์ผ๋ก ์บ์ฑ, ์ดํ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ์บ์ฑ๋ ์ ๋ณด์์ ๊ฐ์ฅ ์ ํฉํ ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ ๋ฐํํ๋ค.
- ์ฐ์ ์์: ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ฅ ๋์ ์ฐ์ ์์
BeanNameUrlHandlerMapping
- ํน์ง: ๋น์ ์ด๋ฆ์ URL๋ก ์ฌ์ฉํ์ฌ ๋งคํ. ์ฆ, ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ๋น์ ์ด๋ฆ๊ณผ ์์ฒญ URL์ด ์ผ์นํ๋ฉด ํด๋น ๋น์ ํธ๋ค๋ฌ๋ก ์ฌ์ฉํ๋ค.
- ์์: <bean name="/home.do" class="com.example.controller.HomeController"/> ์ ๊ฐ์ด ์ค์ ํ๋ฉด '/home.do' ์์ฒญ์ 'HomeController' ๋น์ผ๋ก ๋งคํ
- ์ฌ์ฉ ๋น๋: @RequestMapping ๋ฑ์ฅ ์ดํ๋ก๋ ๊ฑฐ์ ์ฌ์ฉ X
SimpleUrlHandlerMapping
- ํน์ง: ๋ช ์์ ์ผ๋ก URL๊ณผ ํธ๋ค๋ฌ ๋น์ ๋งคํํ๋ ๋ฐฉ์. ์ค์ ํ์ผ์ ์ง์ URL๊ณผ ํธ๋ค๋ฌ๋ฅผ ๋งต ํํ๋ก ์ ์
- ์์:
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">myHelloController</prop>
<prop key="/bye.do">myByeController</prop>
</props>
</property>
</bean>
- ์ฌ์ฉ ๋น๋: @RequestMapping ๋ฑ์ฅ ์ดํ๋ก๋ ๊ฑฐ์ ์ฌ์ฉ X
RouterFunctionMapping (Spring WebFlux)
- ํน์ง: ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ๋ก ๋ผ์ฐํ ์ ์ ์ํ ์ ์๋๋ก ํ๋ HandlerMapping. @Controller ๊ธฐ๋ฐ์ ์ด๋ ธํ ์ด์ ๋ฐฉ์ ๋์ RouterFunction์ ์ฌ์ฉํ์ฌ ์์ฒญ์ ํธ๋ค๋ฌ ํจ์์ ๋งคํํ๋ค.
- ์ฃผ๋ก ์ฌ์ฉ๋๋ ๊ณณ: Spring WebFlux์์ ๋ง์ด ์ฌ์ฉ. Spring MVC์์๋ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
- ์์:
@Configuration
public class RouterConfig {
@Bean
public RouterFunction<ServerResponse> route(MyHandler handler) {
return route(GET("/hello"), handler::hello)
.andRoute(GET("/bye"), handler::bye);
}
}
HandlerMapping์ ์ฐ์ ์์ (Order)
์ฌ๋ฌ ๊ฐ์ HandlerMapping์ด ๋ฑ๋ก๋์ด ์์ ๋, DispatcherServlet์ Ordered ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ฑฐ๋ @Order ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ ์๋ ์ฐ์ ์์(Order)์ ๋ฐ๋ผ HandlerMapping์ ์ํํ๋ค.(๋ฎ์ ์ซ์๊ฐ ๋์ ์ฐ์ ์์)
- ๊ฐ์ฅ ๋์ ์ฐ์ ์์: Ordered.HIGHEST_PRECEDENCE (Integer.MIN_VALUE)
- ๊ฐ์ฅ ๋ฎ์ ์ฐ์ ์์: Ordered.LOWEST_PRECEDENCE (Integer.MAX_VALUE)
DispatcherServlet์ ์ด๊ธฐํ๋ ๋(initHandlerMappings(ApplicationContext context)) ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ๋ชจ๋ HandlerMapping ํ์ ์ ๋น๋ค์ ์ฐพ์ ๋ค ์ ๋ ฌํ์ฌ ๋ด๋ถ์ ์ผ๋ก List ํํ๋ก ์ ์ง
- ๋ชจ๋ HandlerMapping ๋น ์กฐํ
- AnnotationAwareOrderComparator๋ฅผ ํตํ ์ ๋ ฌ
- Ordered ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋น์ getOrder() ๋ฉ์๋ ๋ฐํ ๊ฐ
- @Order ์ด๋ ธํ ์ด์ ์ ์ง์ ๋ ๊ฐ
- ์ ๋ ฌ๋ ๋ฆฌ์คํธ ์ ์ง ํ ์์ฒญ ์ ์์ฐจ์ ์กฐํ
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) { // ์ ๋ ฌ๋ ๋ฆฌ์คํธ ์์ฐจ ์กฐํ
// ๊ฐ HandlerMapping์๊ฒ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์๋ ํธ๋ค๋ฌ๋ฅผ ์์ฒญ
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
// ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ผ๋ฉด ์ฆ์ ๋ฐํํ๊ณ ๋ค์ HandlerMapping์ ์กฐํํ์ง ์์
return handler;
}
}
}
return null; // ๋ชจ๋ HandlerMapping์ด ํธ๋ค๋ฌ๋ฅผ ์ฐพ์ง ๋ชปํจ
}
Default Order
- RequestMappingHandlerMapping: ๊ธฐ๋ณธ์ ์ผ๋ก 0 (๊ฐ์ฅ ๋์ ์ฐ์ ์์)
- SimpleUrlHandlerMapping: Integer.MAX_VALUE - 1 ๋๋ ๊ทธ์ ์คํ๋ ๋งค์ฐ ๋ฎ์ ์ฐ์ ์์
- BeanNameUrlHandlerMapping, ControllerClassNameHandlerMapping: ์คํ๋ง ๋ถํธ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฑ๋ก๋์ง ์๊ฑฐ๋, ๋ฑ๋ก๋๋๋ผ๋ ๋งค์ฐ ๋ฎ์ ์ฐ์ ์์
๋ช ์์ Order
๊ฐ๋ฐ์๋ Order๊ฐ์ ๋ช ์์ ์ผ๋ก ์ง์ ํด ์ฐ์ ์์๋ฅผ ์กฐ์ ํ ์ ์๋ค.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public SimpleUrlHandlerMapping customSimpleUrlHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
Properties urlMappings = new Properties();
urlMappings.put("/customUrl", "myCustomController");
mapping.setMappings(urlMappings);
mapping.setOrder(1); // RequestMappingHandlerMapping (order=0) ๋ณด๋ค ๋ฎ์ ์ฐ์ ์์
return mapping;
}
@Bean
public MyCustomController myCustomController() {
return new MyCustomController();
}
}
'Springboot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] Spring MVC: HandlerAdapter (1) | 2025.06.01 |
---|---|
[Spring] Spring MVC: DispatcherServelt (0) | 2025.05.30 |
[Spring] Spring MVC (0) | 2025.05.29 |
[Spring] ์๋ธ๋ฆฟ๊ณผ ํฐ์บฃ์ ๋ด๋ถ ๊ตฌ์กฐ (0) | 2025.05.17 |
[Springboot] Springboot์ ๋ด๋ถ ์๋ ์๋ฆฌ(With Log) (0) | 2025.05.17 |