Spring 3.1부터 Servlet 3.0을 지원하는데, Servelt 3.0 부터 web.xml 없이 자바 웹 애플리케이션을 배포하는 것이 가능합니다. 따라서 정확히는 스프링 3.1 없이도 web.xml 없는 자바 웹 애플리케이션을 만들 수 있습니다.
그런데.. 조금 귀찮은 부분이 있거든요; 그런 귀찮은 작업을 스프링이 대신 해주고 개발자는 서블릿이나 필터만 등록할 수 있게 해줍니다.
귀찮은 작업엔 뭐가 있냐면… 일단 자바 SPI를 사용하는 방식이기 때문에, META-INF/services 디렉토리에 javax.servlet.ServletContainerInitializer라는 이름의 파일을 만들어 줘야 합니다.
그리고 ServletContainerInitializer의 구현체를 만들고 그 위에 @HandlerTypes라는 애노테이션을 붙이면서 @HandlerTypes 애노테이션 안에.. ServletContainerInitializer의 onStart 메서드의 첫번째 매개변수로 받을 클래스 타입을 명시해 줘야 합니다. 그 타입을 A라고 해보죠.
그럼 이제 A 타입의 구현체를 만들거나, 상속 받은 클래스가 onStart 메서드의 첫번째 매개변수로 전달 됩니다.
귀찮죠;; 그래서 스프링이 다 해뒀고, 우리는 그냥 WebApplicationInitializer 인터페이스만 구현하면 됩니다.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class WebAppIntializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { //parent AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(AppConfig.class); servletContext.addListener(new ContextLoaderListener(rootContext)); // new ContextLoader(rootContext).initWebApplicationContext(servletContext); //child AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext(); dispatcherServletContext.register(WebConfig.class); ServletRegistration.Dynamic dispatcher = servletContext.addServlet("spring", new DispatcherServlet(dispatcherServletContext)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }
|
이렇게요. 이게 web.xml을 대신한다고 보면 됩니다.
나머지 XML은 스프링 빈 설정 파일이 있는데, 스프링 3.0부터 이미 자바로 빈 설정을 할 수 있었습니다. 그런데, 이번 스프링 3.1은 그 기능을 대폭 강화하여 XML 네임스페이스에 해당하는 빈 설정도 자바 설정으로 가능하게 해줍니다. 물론 전부는 아니구요. 일부만요… (그래서 사실 스프링 자바 설정을 그리 많이 사용될 것 같진 않다고 생각합니다.)
|
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
|
@Configuration @EnableTransactionManagement @ComponentScan(basePackages = "whiteship", excludeFilters = {@ComponentScan.Filter(Configuration.class), @ComponentScan.Filter(Controller.class)}) public class AppConfig { @Bean(destroyMethod = "shutdown") public DataSource dataSource(){ return new EmbeddedDatabaseBuilder() .setName("bookDB") .setType(EmbeddedDatabaseType.H2) .addScript("classpath:book-schema.sql") .build(); } @Bean public JdbcTemplate jdbcTemplate(){ return new JdbcTemplate(dataSource()); } @Bean public PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } }
|
자바 설정도 xml 처럼 웹용 설정과 비웹용 설정으로 나눠서 설정할 수 있습니다. 이건 Root ACWAC에서 사용할 비웹용 설정이고…
|
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
|
@Configuration @EnableWebMvc @ComponentScan(basePackages = "whiteship", useDefaultFilters = false, includeFilters = @ComponentScan.Filter(Controller.class)) public class WebConfig extends WebMvcConfigurerAdapter { @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**"); } @Bean public ViewResolver viewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
|
이건 웹용 빈을 설정한 Child ACWAC입니다.
전체 앱은 Github에 올려두었습니다.
https://github.com/keesun/swagger-noxml-mvc
자세한 내용은 이번주 토요일 봄싹 스웨거 책걸이때 말씀드리겠습니다.