전환 사유
- 대부분의 가이드, docs, 자료가 SpringBoot를 전제하고 있어 mvc 프로젝트 유지보수 시 불필요하게 리소스가 낭비되는 부분이 있음.
- @MockBean, @SpyBean 등 SpringBoot의 TC 지원 애너테이션을 사용 할 수 없어 TC 작성 효율이 떨어지고 보일러플레이트 작성에 대한 진입장벽 높음.
- SpringBoot로 전환하는게 장기적으로 유지보수비용이 더 세이브 될 것 같아 전환 결정.
As-is
- spring-webmvc 4.3.4.RELEASE
- 외장 tomcat
- maven
- jsp 코드 다수
- 폴더 기반 deploy (war 사용하지 않고 디렉터리 전체를 배포)
- 폴더 전체 배포는 아무래도 node_modules 같은 디렉터리는 디플로이 시 제외해야 하는 등 신경써야 하는 부분이 생겨서, 애플리케이션 구동 시 필요한 모든 정보를 war에 넣고 war만 배포하는게 유지보수 하기 더 편하다.
전환 방식 검토
- jsp 페이지가 많이 존재하는데, 스프링부트 내장 톰캣은 jsp를 빌트인으로 지원하지 않음.
- jasper를 쓰면 내장 톰캣에서 jsp 쓸 수 있다지만, 100% 호환 될지 우려되는 부분이 있어 이런 변수를 늘리면서 무리하게 executable jar 사용할 필요는 없어보임.
- 또는 jsp 페이지를 모두 Thymeleaf 등으로 전환하는 방법도 있겠지만, 무리해서 일시에 전환하기 보다는 점진적으로 진행 할 수 있도록 전환 계획을 아래와 같이 수립.
단계별로 전환하기
- 의존성 spring mvc → springboot로 변경하고 설정 잡기 (외장 tomcat, jsp, 폴더기반 배포는 유지)
- jsp를 Thymeleaf 등으로 마이그 (시간 날 때 진행)
- 외장 tomcat 걷어내고 내장 tomcat 사용. jar 패키징 및 배포
의존성 spring mvc → springboot로 변경하고 설정 잡기
1-1. 의존성 세팅
1
2
3
4
5
6
7
8
9
10
11
12
| <groupId>dev.umbum</groupId>
<artifactId>web</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>my-jsp-web</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.9</version>
<relativePath/>
</parent>
... 기존 의존성들 충돌 안나게끔 정리
|
- 외장톰캣, war(폴더 기반 배포) 사용 할 것이기 때문에 embedded-tomcat, jasper 의존성 필요없음.
- 빌드 한 번 돌려본다.
빌드 성공하면 다음으로
1-2. WebApplicationInitializer 전환
- 기존 spring-webmvc 프로젝트에는 xml 기반 설정이라면 web.xml 설정파일이, java 기반 설정이라면 WebApplicationInitializer를 직접 구현한 구현체가 있을텐데 이를 마이그 해주어야 한다.
- java 기반 설정 (WebApplicationInitializer) 되어 있는 경우 예시 (아래 코드)
1
2
3
4
5
6
7
8
9
10
| public class WebApplicationInitializerImpl implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) throws ServletException {
// servlet listener 등록
// servlet filter 등록
// property source 설정
// spring.profiles.active 설정
기타 다양한 설정
}
}
|
- spring-webmvc의 애플리케이션 진입점은 WebApplicationInitializer.onStartup 이므로, 이 부분을 제거해주고, SpringBoot의 애플리케이션 진입점인 @SpringBootApplication 를 설정해준다.
1
2
3
4
5
6
7
8
9
10
| @SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
... 기타 수동으로 설정하고 있기 때문에 AutoConfig 타면 안되는 항목들
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @Configuration
public class ServletConfig {
@Bean
public ServletListenerRegistrationBean<LogbackShutdownListener> logbackShutdownListener() {
ServletListenerRegistrationBean<LogbackShutdownListener> registrationBean = new ServletListenerRegistrationBean<>();
registrationBean.setListener(new LogbackShutdownListener());
return registrationBean;
}
@Bean
public FilterRegistrationBean<XssEscapeServletFilter> xssEscapeServletFilter(){
FilterRegistrationBean<XssEscapeServletFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new XssEscapeServletFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setMatchAfter(true);
return registrationBean;
}
}
|
1
2
3
4
5
6
7
| spring.profiles.active=@environment@
spring.config.import=classpath:common.properties, classpath:web.properties
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
## https://www.baeldung.com/spring-mvc-content-negotiation-json-xml#basics-1 참고
spring.mvc.pathmatch.matching-strategy=ant-path-matcher
|
기존에 maven 사용하고 있었기 때문에 profile은 maven에서 변수로 넘겨받아 @environment@로 세팅.
[Spring] profile로 alpha, beta, real 빌드 구분하기
- 마지막으로 기존 WebApplicationInitializer의 구현체를 아예 삭제해주고, SpringBootServletInitializer를 상속한 클래스를 만들어준다.
1
2
3
4
5
6
| public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
|
여기까지 하고 기존처럼 외장 tomcat에서 애플리케이션 실행해본다. 서버 잘 뜨면 다음으로.
- EnableWebMvc와 WebMvcConfigurer 의 관계
- 기존에 WebMvcConfigurerAdapter를 상속하던 Bean이 있다면 이를 WebMvcConfigurer 구현으로 바꿔준다.
- @EnableWebMvc는 삭제해준다.
- viewResolver 설정, argumentResolver 설정을 최신화 해준다.
1
2
3
4
5
6
7
8
9
10
| public class WebMvcConfigurerImpl implements WebMvcConfigurer {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/{경로잡아준다}", ".jsp");
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(myArgumentResolver);
}
|
1-4. /build/ 로 접근했을 때 webapp/build/index.html 반환하도록 매핑하기
1
2
3
4
| @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/build/").setViewName("forward:/build/index.html");
}
|
1-5. boot로 변경하면서 spring 4 -> 5로 버전업 했다면 호환성 체크
전환 1단계 끝.
생각 보다 간단하게 전환 할 수 있다.
이제 maven을 gradle로 전환한다거나, jsp를 걷어낸다거나, 내장 tomcat을 사용한다거나 하는 것들을 차차 진행하면 된다. 추가 내용 참고 -https://www.baeldung.com/spring-boot-migration