HttpServlet 추상 클래스 서비스 메소드로 요청을 받는다
if (method.equals("GET")) { // get 방식으로 요청받으면 해당 조건을 탄다
long lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp); // doGet 실행
해당 doGet 메소드는 FramewrokServlet 추상 클래스의 doGet 메소드 실행된다
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
processReuqest 에서 doService 실행
DispatcherServlet 에서 doService 실행 그러면 this.doDispatch(request, response); 가 실행된다
handler 선택하는 메소드
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for(HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
RequestMappingHandlerMapping 이 선택된다
이 선택되는 과정은 AbstractHandlerMapping 추상 클래스에서
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = this.getHandlerInternal(request); // 내부적으로 handler 선택하겠다
AbstractHandlerMethodMapping 추상 클래스 getHandlerInternal 실행
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = this.initLookupPath(request);
this.mappingRegistry.acquireReadLock();
HandlerMethod var4;
try {
HandlerMethod handlerMethod = this.lookupHandlerMethod(lookupPath, request);
var4 = handlerMethod != null ? handlerMethod.createWithResolvedBean() : null;
} finally {
this.mappingRegistry.releaseReadLock();
}
return var4;
}
mappingRegistry 를 사용한다
매핑 메타데이터를 사용하는 것이다
이렇게 해서 handler 를 가져오는데 리턴하고 다시 AbstractHandlerMapping 클래스에서
HandlerExecutionChain executionChain = this.getHandlerExecutionChain(handler, request); // 이 메소드로
---
이건 getHandlerExecutionChain(Object handler, HttpServletRequest request) 메소드
HandlerExecutionChain chain = var10000;
for(HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor mappedInterceptor) {
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
chain.addInterceptor(interceptor);
}
}
return chain;
인터셉터 넣어서 리턴
컨트롤러 호출 전에 인터셉터가 있으면 실행하고 호출해야 하기 때문에 넣는다
최종적으로 interceptor 까지 담긴 handler 가 리턴된다
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
// handler adapter 얻고 handler 실행
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
아래 메소드가 실행
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.handleInternal(request, response, (HandlerMethod)handler);
}
리플렉션 사용해서 핸들러 메소드 호출한다
mav = this.invokeHandlerMethod(request, response, handlerMethod);
InvocableHandlerMethod 클래스에서
invokeForRequest 메소드에서
Object returnValue = this.doInvoke(args); 이렇게 doInvoke 호출한다
doInvoke 보면
return method.invoke(this.getBean(), args);
이렇게 메소드를 invoke 한다
getBean 은 실행할 컨트롤러가 들어간다
RequestMappingHandlerAdapter 클래스에서 invokeHanlderMethod 에서 최종적으로
getModelAndView 메소드가 호출된다
뷰이름과 모델정보를 담아서 리턴한다
DispatcherServlet 클래스에서 processDispatchResult 이 메소드를 호출하여 뷰와 모델을 렌더한다