티스토리 뷰

반응형

스프링에서 servlet-context.xml과 같은 xml파일에서 bean을 정의하고 여러가지 설정을 하는데, 이를 xml파일이 아닌 자바 클래스로 구현을 해보겠다. xml에 비해 짧고 간단하게 설정할 수 있어 편리한 장점을 가지고 있다.

 

1. Java 설정 클래스

@Configuration
public class AppConf {
    @Bean
    public MemberDao memberDao(){
     return new MemberDao();
    }
}

설정 클래스로 사용할 클래스 위에 @Configuration 애노테이션을 붙여준다.

스프링은 이 애노테이션이 붙은 설정 클래스를 내부적으로 스프링 빈으로 등록한다.

@Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용하여 해당 클래스에서 Bean을 등록하고자 함을 명시해주어야 한다. 메서드를 작성하고 @Bean을 붙여서 빈을 정의한다. 메서드명이 빈의 id와 마찬가지이다.

스프링 컨테이너가 생성한 빈은 싱글톤 객체이다. 즉, 한개의 객체만 생성한다. 다른 설정 메서드에서 memberDao()를 여러 번 호출하더라도 항상 같은 객체를 리턴한다.

 

2. 스프링 MVC 설정 클래스

이제 스프링 MVC를 사용하기 위해 설정할 설정 클래스를 만들어보겠다.

주요 설정으로 HandlerMapping, ViewResolver등이 있고, DispatcherServlet 설정을 해줘야한다.

@Configuration
@EnableWebMvc
@ComponentScan("webprj.board.controller")
public class ServletConfig implements WebMvcConfigurer {
  // 정적 콘텐츠 처리  설정
  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    // 고정적인 리소스에 대한 요청을 직접 처리하지 않고, 서블릿 컨테이너의 디폴트 서블릿 전달 요청
    configurer.enable();
  }

  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
    registry.jsp("/WEB-INF/views/",".jsp");
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("/static/");
  }

  @Bean
  public StringHttpMessageConverter stringHttpMessageConverter() {
    final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
    stringConverter.setSupportedMediaTypes(
          Arrays.asList(MediaType.TEXT_PLAIN, MediaType.TEXT_HTML, MediaType.APPLICATION_JSON));
    return stringConverter;
  }

  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(stringHttpMessageConverter());
  }
}
  • @ComponentScan("패키지 경로") 애노테이션은 @Component어노테이션 및 streotype(@Service, @Repository, @Controller.)어노테이션이 부여된 Class들을 자동으로 Scan하여 Bean으로 등록해주는 역할을 하는 어노테이션이다. 이전에 xml파일에 <context:component-scan base-package="패키지 경로"/>를 이용해 지정해주었던 것을 Java파일을 이용하여 bean을 scan하기 위해서 생긴 애노테이션이다.

  • @EnableWebMvc 애노테이션은 스프링 MVC 설정을 활성화한다. 스프링 MVC를 사용하는데 필요한 다양한 설정을 생성한다. 직접 처음부터 끝까지 구성하려면 설정이 매우 복잡해지는데, 이를 일일이 구성하지 않아도 이 복잡한 설정을 대신 스프링이 해주는 것이 이 애노테이션이다. @Controller 타입의 핸들러 객체를 처리하기 위한 RequestMappingHandlerMapping이나 RequestMappingHandlerAdapter 클래스를 빈으로 등록해준다.

  • WebMvcConfigurer 인터페이스는 스프링 MVC의 개별 설정을 조정할 때 사용한다. 자바8부터 지원하는 디폴트 메서드를 이용해서 WebMvcConfigurer 인터페이스의 메서드에 기본 구현을 제공하고 있다. 기본 구현은 모두 빈 내용의 구현이다. 즉, 상속한 클래스에서는 재정의가 필요한 메서드만 구현하면 된다.

    configureDefaultServletHandling 메서드를 재정의 하면서 디폴트 서블릿 설정을 조정한다. DispatcherServlet 의 매핑 경로를 '/' 로 주었을 때 JSP/HTML/CSS 등을 올바르게 처리하기 위한 설정을 추가하는 것이다. 이외에 ViewResolver 라든지 여러가지 설정을 재정의한다. 이에 관해서는 아래 내용에 자세히 설명하겠다.

 

디폴트 핸들러와 HandlerMapping의 우선순위

DispatcherServlet의 매핑 경로가 '/'인 경우에 .jsp로 끝나는 요청을 제외한 모든 요청을 DispatcherServlet이 처리한다.

확장자가 .jsp가 아닌 /css/header.css나 /index.html과 같은 모든 요청 또한 DispatcherServlet이 처리한다.

이 때 @EnableWebMvc 애노테이션이 등록하는 HandlerMapping은 컨트롤러 객체의 요청 경로만 대응할 수 있다.

즉 /list 와 같은 경로는 처리할 수 있지만 /index.html같은 요청은 컨트롤러 객체는 찾지못해 404 오류가 난다.!😨

 

이걸 방지하기 위해서 WebMvcConfigurer의 configureDefaultServletHandling() 메서드를 재정의하는 것이다.

위에 코드에도 있듯이 configurer.enable() 메서드를 살펴보자.

enable() 메서드는 DefaultServletHttpRequestHandlerSimpleUrlHandlerMapping 두 빈 객체를 추가한다.

 

DefaultServletHttpRequestHandler는 클라이언트의 모든 요청을 WAS가 제공하는 디폴트 서블릿에 전달해서 처리하도록 한다. 그리고 SimpleUrlHandlerMapping은 모든 경로에 대해 DefaultServletHttpRequestHandler를 리턴한다.

 

 

RequestMappingHandlerMapping이 SimpleUrlHandlerMapping의 우선순위보다 높다는 점을 기억하고 순서를 정리해보자.

  1. RequestMappingHandlerMapping을 사용해서 요청을 처리할 핸들러를 검색하고 존재한다면 해당 컨트롤러를 이용해서 요청을 처리한다.
  2. 존재하지 않으면 SimpleUrlHandlerMapping을 사용해서 요청을 처리할 핸들러를 검색한다.
    모든 경로에 대해 DefaultServletHttpRequestHandler를 리턴한다.
    DisptcherServlet은 DefaultServletHttpRequestHandler에게 처리를 요청한다.
    DefaultServletHttpRequestHandler는 디폴트 서블릿에 처리를 위임한다.

이 순서대로라면 /index.html 경로로 요청이 들어오면 1번 과정에서 컨트롤러를 찾지못하기 때문에 2번 과정의 디폴트 서블릿이 요청을 처리하게 된다!!물론 404 오류도 나지 않고 정상 처리된다!

 

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday