티스토리 뷰
[ Spring ] Java 설정 파일 사용 및 설명 (@Configuration, @Bean, @EnableWebMvc)
통통푸딩 2021. 2. 19. 01:55스프링에서 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() 메서드는 DefaultServletHttpRequestHandler와 SimpleUrlHandlerMapping 두 빈 객체를 추가한다.
DefaultServletHttpRequestHandler는 클라이언트의 모든 요청을 WAS가 제공하는 디폴트 서블릿에 전달해서 처리하도록 한다. 그리고 SimpleUrlHandlerMapping은 모든 경로에 대해 DefaultServletHttpRequestHandler를 리턴한다.
RequestMappingHandlerMapping이 SimpleUrlHandlerMapping의 우선순위보다 높다는 점을 기억하고 순서를 정리해보자.
- RequestMappingHandlerMapping을 사용해서 요청을 처리할 핸들러를 검색하고 존재한다면 해당 컨트롤러를 이용해서 요청을 처리한다.
- 존재하지 않으면 SimpleUrlHandlerMapping을 사용해서 요청을 처리할 핸들러를 검색한다.
모든 경로에 대해 DefaultServletHttpRequestHandler를 리턴한다.
DisptcherServlet은 DefaultServletHttpRequestHandler에게 처리를 요청한다.
DefaultServletHttpRequestHandler는 디폴트 서블릿에 처리를 위임한다.
이 순서대로라면 /index.html 경로로 요청이 들어오면 1번 과정에서 컨트롤러를 찾지못하기 때문에 2번 과정의 디폴트 서블릿이 요청을 처리하게 된다!!물론 404 오류도 나지 않고 정상 처리된다!
'Java > 개념정리' 카테고리의 다른 글
[Java] 데이터 타입, 변수, 배열 (0) | 2021.09.19 |
---|---|
[ Java ] JVM란? 자바의 실행 원리 알아보기 (0) | 2021.09.14 |
[ Java ] JDBC - PreparedStatement (0) | 2020.12.08 |
[ Java ] JDBC 사용하는 방법 (0) | 2020.12.08 |
[ Java ] 자바 Stream (스트림) 사용 방법 정리 (0) | 2020.11.28 |