제목에서 "web.xml을 없앤다"는 조금은 이상할 수 있는 말을 했습니다. 없앤다는 표현이 정확한것인지는 모르겠습니다만, Java Class 파일을 이용해 web.xml의 설정을 대신하기 때문에 결론적으로 web.xml을 삭제해도 정상 동작하게됩니다. 이번 포스팅에서는 web.xml을 이용하지 않는 Spring WebApplication을 만들어보겠습니다.
Spring학습을 하시면 보통의 경우 web.xml이 생성되어지는 프로젝트를 만들어 학습을 하게됩니다. 또 컨테이너가 초기화 될때 이 web.xml에 적혀있는 정보를 토대로 초기화 하기 때문에, web.xml을 설정하는 방법을 배우게 되죠. 하지만 SpringBoot를 이용해 프로젝트를 먼저 진행해보신 분들이라면, SpringBoot 프로젝트에는 web.xml이 안보이셨을 겁니다.
바로 SpringBoot
에서는 내장톰캣을 사용하며 이 내장톰캣
의 설정파일(기존 web.xml)
을 web.xml이 아닌 Java Class 파일을 이용해 설정을 하기 때문입니다. web.xml을 사용하는 경우 문법이 조금만 틀려도 실행이 되지 않는다는 단점이 있었고, 이를 잘 작성하기도 어려웠습니다. 그 때문에 java Class를 이용한다고 합니다.
바로 위의 SpringBoot에서 처럼 SpringMVC에서도 web.xml을 이용하지 않고 Java Class를 이용해 설정을 할 수 있는 방식이 있습니다. 조금더 자세히 알아보겠습니다.
Spring MVC web.xml 파일 대신 Java Class로 설정하기
1. WebApplication Class
우선 WebApplication Class를 생성합니다.
x
public class WebApplication implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
}
}
그 후 WebApplicationInitializer
를 구현합니다. 이 인터페이스를 구현하면 onStartup()
이라는 메소드를 구현하게 되는데요, 이 메소드는 이름과 같이 WebApplication이 초기화 되는 시점에 호출되기 때문에 마치 web.xml의 설정파일 처럼 사용할 수 있습니다. 그 때문에, 매개변수로 주어지는 servletContext
에 필요한 servletMapping, listener, Filter
들을 등록할 수 있습니다.
IoC Container(ApplicationContext)생성
xxxxxxxxxx
public class WebApplication implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setServletContext(servletContext);
context.register(WebConfig.class);
context.refresh();
}
}
우선 DispatcherServlet
을 등록하기 전에 DispatcherServlet에서 사용할 IoCContainer를 생성하고 설정해야겠죠? 저희는 Annotation 기반의 설정을 할 것이기 때문에 구현체인 AnnotationConfigApplicationContext
를 사용하겠습니다. 그 후 context.register();
메소드를 이용해 이전에 만들어 두었던 WebConfig
클래스를 등록해주고, 마지막으로 refresh()를 해줍니다. 추가적으로 IoC Container(ApplicationContext)의 setServletContext() 메소드를 이용해 ServletContext를 등록해주어야 하는데, 이는 종종 IoC Container에서 ServletContext를 참조하는 코드가 있기 때문입니다.
public class WebConfig{}
이전 포스팅에 이미 있지만 되돌아가기 귀찮으신 분들을 위해 다시한번 작성합니다. WebConfig는 web.xml
에 bean설정들을 하지 않고 또, 그 bean설정을 한 파일의 위치를 web.xml에 작성하지 않도록하기 위해서, @Configuration
을 이용해 Bean설정 파일임을 알려주고, @ComponentScan
을 이용해 이 클래스가 위치한 곳을 기반으로 Streotype
의 어노테이션을 가지고 있는 모든 Bean을 자동으로 scan하여 IoC Container에 등록해주도록 했습니다.
DispatcherServlet 생성과 Mapping
public class WebApplication implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
context.refresh();
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.addMapping("/app/*");
}
}
마지막 단계입니다. 우리가 생성한 IoC Container
를 매개변수로하여, DispatcherServlet
을 생성합니다. 그 후 onStartup()
메소드의 인자로 전달된 ServletContext
객체의 addServlet()
메소드를 이용해, DispatcherServlet을 등록합니다.
마지막으로 위의 addServlet()
의 반환값으로 전달되는 ServletRegistration.Dynamic 객체를 이용해 addMapping()
을 호출하여 DispatcherServlet에 mapping될 url을 지정해주면 됩니다.