getter
요소에 대한 getter
@Nullable
public final MultipartResolver getMultipartResolver() {
return this.multipartResolver;
}
@Nullable
public final List<HandlerMapping> getHandlerMappings() {
return this.handlerMappings != null ? Collections.unmodifiableList(this.handlerMappings) : null;
}
getter에서 mutlpartResolver, handlerMappings는 말그대로 dispatcherServlet이 갖는 속성값을 반환해준다.
크게 얘기할 부분이 없다.
request에 사용되는 getter
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
@Nullable
protected String getDefaultViewName(HttpServletRequest request) throws Exception {
return this.viewNameTranslator != null ? this.viewNameTranslator.getViewName(request) : null;
}
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
Iterator var2 = this.handlerAdapters.iterator();
while(var2.hasNext()) {
HandlerAdapter adapter = (HandlerAdapter)var2.next();
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
getHandler
getHandler는 요청을 매개변수로 받고 이에 해당하는 handler를 handlerMappings에서 찾아서 반환하는 역할을 한다.
후에 doDispatch 메서드를 보면 getHandler를 호출하고 null이면 noHandlerFound Exception을 던지는 것을 확인할 수 있다.
getDefaultViewName
말그대로 defaultViewName을 반환하는 역할을 한다. applyDefaultViewName 메서드에서 요청으로부터 viewName을 받아서 ModelAndView에 설정할 때 사용된다.
getHandlerAdapter
handler를 매개변수로 받고 이에 해당하는 adapter를 반환하게 된다. adapter는 controller를 호출하게 되는데 이 때, 요청에 해당하는 handler를 처리할 수 있는 adapter를 찾는 역할을 한다.
spring의 dispatcherServlet은 Strategy 패턴을 잘 활용한다. 이전 포스팅에서 봤던 init을 할 때 초기화된 요소들이 dispatcherServlet에서 사용되는 strategy의 인터페이스가 되고, 해당 인터페이스에 대한 여러 개의 strategy 구현체 코드를 만들 수 있다.
예를들어, HandlerMapping의 경우 RequestMappingHandlerMapping, SimpleUrlHandlerMapping, BeanNameHandlerMapping을 사용한다. HandlerAdapter의 경우에도 이와 비슷하게 인터페이스에 대한 다양한 구현체 Strategy를 사용한다.
protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
List<T> strategies = this.getDefaultStrategies(context, strategyInterface);
if (strategies.size() != 1) {
throw new BeanInitializationException("DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
} else {
return strategies.get(0);
}
}
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
if (defaultStrategies == null) {
try {
ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException var15) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + var15.getMessage());
}
}
String key = strategyInterface.getName();
String value = defaultStrategies.getProperty(key);
if (value == null) {
return Collections.emptyList();
} else {
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList(classNames.length);
String[] var7 = classNames;
int var8 = classNames.length;
for(int var9 = 0; var9 < var8; ++var9) {
String className = var7[var9];
try {
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
Object strategy = this.createDefaultStrategy(context, clazz);
strategies.add(strategy);
} catch (ClassNotFoundException var13) {
throw new BeanInitializationException("Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", var13);
} catch (LinkageError var14) {
throw new BeanInitializationException("Unresolvable class definition for DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", var14);
}
}
return strategies;
}
}
getDefaultStrategy는 resolver, requestToViewNameTranslator, FlashMapManager를 초기화할 때 해당하는 전략을 가져오기 위해 사용된다.
getDefaultStrategies는 handlerMappings, handlerAdapters, ExceptionResolvers, ViewResolvers를 초기화할 때 1개 이상의 전략들을 가져오기 위해 사용된다.
각 요소마다 전략들을 갖기 때문에 이에 대해서는 각각의 코드를 뜯어보면서 살펴볼 예정이다.
setter
public void setDetectAllHandlerMappings(boolean detectAllHandlerMappings) {
this.detectAllHandlerMappings = detectAllHandlerMappings;
}
public void setDetectAllHandlerAdapters(boolean detectAllHandlerAdapters) {
this.detectAllHandlerAdapters = detectAllHandlerAdapters;
}
public void setDetectAllHandlerExceptionResolvers(boolean detectAllHandlerExceptionResolvers) {
this.detectAllHandlerExceptionResolvers = detectAllHandlerExceptionResolvers;
}
public void setDetectAllViewResolvers(boolean detectAllViewResolvers) {
this.detectAllViewResolvers = detectAllViewResolvers;
}
public void setCleanupAfterInclude(boolean cleanupAfterInclude) {
this.cleanupAfterInclude = cleanupAfterInclude;
}
Spring의 요청 처리 흐름을 구성하는 다양한 전략 컴포넌트들을 초기화하거나 설정할 때 사용된다.
setter는 요청 처리 시 사용할 구성 요소들을 자동으로 검색할지 여부를 결정하거나, DispatcherServlet의 동작 방식을 조정하는 데 사용된다.
위 setter 값들은 아래와 같이 dispatcherServlet에 default 값이 설정되어 있는데 이 값들은 공통적으로 사용할 빈들을 검색할 범위를 나타낸다.
true인 경우 모든 빈들을 검색하여 사용할 빈을 결정하고, false로 설정된 경우 우선 순위가 가장 높은 하나의 빈만을 사용하게 된다.
private boolean detectAllHandlerMappings = true;
private boolean detectAllHandlerAdapters = true;
private boolean detectAllHandlerExceptionResolvers = true;
private boolean detectAllViewResolvers = true;
private boolean throwExceptionIfNoHandlerFound = true;
private boolean cleanupAfterInclude = true;
굳이 false로 설정할 일도 없을 것 같고, dispatcherServlet 설정값을 건드릴 일은 없으니 이후에 handlerMapping부분이나 adapter 부분을 정리하면서 다시 살펴보려 한다.
'Web > Spring' 카테고리의 다른 글
[Spring Web 6.1] DispatcherServlet 뜯어보기 - Multipart & ExceptionHandling (1) | 2024.10.07 |
---|---|
[Spring Web 6.1] DispatcherServlet 뜯어보기 - view 관련 (0) | 2024.10.07 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - dispatch (0) | 2024.10.07 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - Constructor & init (0) | 2024.10.04 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - Deprecated & Static (0) | 2024.10.04 |