티스토리 뷰
반응형
DispatcherServlet의 ViewResolver
- DispatcherServlet 동작과정에서 viewResolver의 과정을 살펴보자
//DispatcherServlet.class
protected void initStrategies(ApplicationContext context) {
...
//0. init은 최초의 서블릿을 initializer할 때만 접근한다.
this.initViewResolvers(context);
...
}
private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;
if (this.detectAllViewResolvers) {
//1. viewResolver 타입을 모두 찾아온다.
Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
} else {
try {
//2. 특정 viewResolver 타입을 찾아온다. (잘 사용하지 않는다.)
ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class);
this.viewResolvers = Collections.singletonList(vr);
} catch (NoSuchBeanDefinitionException var3) {
}
}
if (this.viewResolvers == null) {
//3. 기본 viewResolver(prefix, suffix)가 등록되어 있지 않다면 기본 viewResolver를 찾아온다.
this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No ViewResolvers declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
}
}
}
- viewResolver가 커스텀되어 있다면, 사용자 설정에 맞게 view를 노출해주고, 커스텀 되어있지 않는다면 기본 viewResolver를 사용하여 화면에 노출(사용자는 controller return 값에 절대경로 및 확장자까지 모두 작성해줘야 한다.)해준다.
ViewResolver 및 HandlerMapping, HandlerAdapter 등이 없을 시 해당 properties에 명시
(기본 viewResolver 세팅 위치)
#DispatcherServlet.properties
...
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
...
그럼 커스텀 ViewResolver를 만들어보자
-
커스텀 Bean을 등록하자 (ViewResolver)
@Configuration @ComponentScan public class WebConfig { @Bean public ViewResolver viewResolver() { //기본적으로 제공되는 ViewResolver의 설정은 커스텀해보자 InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); //return 값의 경로와 확장자를 미리 지정한다. viewResolver.setPrefix("/WEB-INF/"); //절대경로 viewResolver.setSuffix(".jsp"); //확장자 return viewResolver; } }
-
ViewResolver 설정에 따른 Controller의 변화
//SimpleController @Controller("/simple") public class SimpleController implements org.springframework.web.servlet.mvc.Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { // /WEB-INF/simple.jsp에서 변경됨. return new ModelAndView("simple"); } } //HelloController @Controller public class HelloController { ... @GetMapping("/sample") public String sample() { // /WEB-INF/simple.jsp return "sample"; } }
-
디버깅을 통해 initViewResolver가 어떤 조건문에서 실행되나 확인해보자.
private void initViewResolvers(ApplicationContext context) { this.viewResolvers = null; if (this.detectAllViewResolvers) { Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false); //1. 현재 우리는 Bean을 등록해놓았으므로(viewResolver()) 이 조건을 타게 된다. if (!matchingBeans.isEmpty()) { this.viewResolvers = new ArrayList(matchingBeans.values()); AnnotationAwareOrderComparator.sort(this.viewResolvers); } } else { try { ViewResolver vr = (ViewResolver)context.getBean("viewResolver", ViewResolver.class); this.viewResolvers = Collections.singletonList(vr); } catch (NoSuchBeanDefinitionException var3) { } } //2. 현재 우리는 viewResovler에서 prefix와 suffix를 등록해놓았기 때문에 해당 조건은 타지 않게 된다. if (this.viewResolvers == null) { this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class); if (this.logger.isTraceEnabled()) { this.logger.trace("No ViewResolvers declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties"); } } }
1. 현재 Bean을 등록해놓았으므로(viewResolver()) 이 조건을 타게 된다.
2. 현재 viewResovler에서 prefix와 suffix를 등록해놓았기 때문에 해당 조건은 타지 않게 된다.
▶ init은 최초의 서블릿을 initializer할 때만 접근한다.
반응형
'Spring > Spring 웹 MVC' 카테고리의 다른 글
[스프링 웹 MVC] 스프링 MVC 빈 설정 (0) | 2020.04.06 |
---|---|
[스프링 웹 MVC] 스프링 MVC 동작 원리 정리 (0) | 2020.03.18 |
[스프링 웹 MVC] DispatcherServlet 동작원리(2) (0) | 2020.03.13 |
[스프링 웹 MVC] DispatcherServlet 동작원리(1) (0) | 2020.03.13 |
[스프링 웹 MVC] 스프링 MVC 연동(Dispatcher Servlet) (0) | 2020.03.13 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- springboot
- 점층적 생성 패턴
- 복사 팩토리
- 연관관계
- try with resources
- 인프런
- jdk버전
- junit
- @Lazy
- 생성자
- try catch finally
- 팩토리 메소드 패턴
- 자바8
- java
- Spring
- 빈 순환 참조
- flatMap
- 이펙티브자바
- 김영한
- mustache
- Effective Java
- effectivejava
- package-private
- JPA
- 스프링부트
- ifPresent
- 정적팩터리메서드
- 빌더 패턴
- 이펙티브 자바
- java8
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함