[미세먼지 Tip] Spring Boot Live Reload
2022. 02. 06.
오… 이게 기본 옵션이 아니구나
오늘 김영한님의 Spring Boot 입문 강의를 듣기 시작했다. 굉장히 기본 세팅을 하고, static index 페이지를 잡아주고, 템플릿 엔진으로 동적으로 움직이는 페이지를 하나 만들었다. 그런데 영한님께서 계속 프로젝트를 껐다 켜야한다고 하셨다. 기존에 React의 Hot Reload에 길들여져버린 나에게 굉장히 불편하게 느껴졌다.
영한님께서 강의 노트에 spring-boot-devtools
라이브러리를 추가하면 서버 재시작 없이 변경사항을 적용할 수 있다고 하셔서 바로 검색해 보았다.
일단 깔자!
node에서 package.json
이 있듯, Spring Boot에서는 대개 Gradle 이라는 빌드 관리 시스템을 사용한다. Spring Boot 프로젝트 최상단에 있는 build.gradle
에 dependencies
부분을 다음과 같이 수정한다.
dependencies {
// ... 기존 디펜던시들
// 아래 녀석을 추가해주자!
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
IntelliJ를 사용하면 해당 파일에 수정을 가하자 마자 Gradle Changes를 적용할 수 있는 버튼이 나타난다.
눈에 띄면 바로 클릭하면 되고, 아니면 Ctrl + Shift + O
를 통해서 Gradle의 변경 사항을 적용해줄 수 있다.
IntelliJ의 설정을 변경해주자
이제 IntelliJ의 설정을 잡아주어야 한다. 확실히 node 생태계와 조금 다르게 IDE와 프레임워크, 언어가 유기적으로 붙어서 움직인다는 느낌이 들었다. (그리고 VSCode로 Spring Boot 개발을 하면 정말 많은 Configuration을 해야 할 것 같다는 느낌도 들었다)
- 상단 메뉴에서 File - Settings(mac에서는 Preference) 을 열어준다.
- 좌측 메뉴에서
Build, Execution, Deployment - Compiler
로 가보자. (Build, Execution, Deployment
는 펼치기 화살표,Compiler
는 그냥 클릭) - 그러면 체크 메뉴들 중에
Build Project automatically
가 있다. 이 녀석이 아마 체크 해제 되어있을 텐데, 체크 해주자. - IntelliJ 버전에 따라 다른데, 내가 사용하는 버전에서는 Settings 최상단 메뉴에
Advanced Settings
가 있다. 그 곳으로 가보자. - 그러면 Compiler 관련 항목에
Allow auto-make to start even if developed application is currently running
이 있다. 이 녀석도 체크 해제 되어있을 텐데, 체크 해주자. - 그리고 Settings 에서 OK 를 눌러 저장하고 닫아주자.
일단 된다! 근데… 원래 이런가?
그리고 이 상태로 Spring Boot에서 사용하는 controller 등의 코드를 변경하면 조금 기다리면 알아서 재시작이 된다.
근데… 갑갑하다! node로 개발할 때는 저장 누르는 순간 휘리릭~ 뿅! 재시작이 됐는데, Spring은 약간의 딜레이가 걸린다. 이럴 바에는 그냥 Shift + F10
을 입력해서 프로젝트를 아예 재시작하는게 빠르겠다는 생각이 들 정도이다. 구글링을 통해 다음의 글을 발견했다.
Can’t get devtools auto build service working on Windows…
위 글에 따르면, 몇 가지의 IntelliJ 레지스트리 설정을 통해서 지연을 줄일 수 있다고 되어있다.
Ctrl + Shift + A
혹은 상단의Help - Find Action
으로 Action 실행 검색창을 열고, 그 곳에Registry
를 검색하여 열어주자.- 그리고 다음의 설정들을 변경해주자.
- compiler.document.save.enabled - 문서(코드)의 변경에 대해 프로젝트를 저장할지에 대한 여부를 지정한다. 일종의 자동 저장 옵션이다. 처음에는 활성화 해서 사용했는데, 아래 설정들에 맞물려서 강제로 자동저장을 매우 빨리 하게 됐고, 실질적으로 코딩을 할 수가 없었다. 그래서 사용하지 않기로 했다. 아래의 설정들을 잘 이해하고 계시다면 켜둬도 될 것 같지만 잘 모르겠다면 그냥 끈 상태로 사용하자.
- compiler.document.save.trigger.delay - 문서(코드) 변경에 대한 반응으로 저장을 트리거하기 전의 지연 시간(ms 단위)이다. 나는 100으로 설정했다.
- compiler.automake.postpone.when.idle.less.than - Autobuild가 시작하려는 순간에 IntelliJ가 지정된 값(ms 단위) 미만의 간격으로 Idle 상태이면 사용자의 작업을 방해하지 않도록 Autobuild를 미루는 옵션이다. 빌드가 시작하려고 하는데 내가 코드에 변경을 가한다던가 할 수 있으니, 그동안은 빌드를 미루는 것. 이것도 100으로 설정했다.
- compiler.automake.trigger.delay - 파일시스템 이벤트가 생기면 Auto make를 얼마나 미룰지에 대한 지연 시간(ms 단위) 이것도 100으로 설정했다.
위 처럼 설정해주니, 확실히 반응속도가 조금 빨라지긴 했다. 완전 즉각적으로 반응하지는 않는데, Spring Boot가 새로 빌드되면서 실행되어야 하다 보니, 어느정도의 지연 시간이 걸리는 듯도 하다. 자세한 이유는 모르겠다. (사실 이것 때문에 아직도 조금 갑갑하다)
템플릿도 바꾸면 반영 ‘해줘’
위의 설정을 하면 Controller의 코드를 바꿨을 때는 자동 재시작이 된다. 그런데 Thymeleaf와 같은 템플릿 엔진을 사용할 때 템플릿의 내용을 바꾸어도 서버가 재시작되거나 반영이 되지 않는 것을 발견했다. 이는 Spring 컨테이너에서 viewResolver가 Resource인 템플릿을 실시간으로 읽어오지 않기 때문인 것으로 보인다. (오개념일 수 있습니다. 혹시 잘 아시는 분 있으면 지적해주세요 ㅠㅠ) 확실한 내용은 조금 더 스터디를 해봐야 할 것 같다. 일단 해결법은 다음과 같다.
- 이미지 위치에 있는 곳을 클릭한다. 그러면
Edit Configuration
이 나오는데, 이것을 클릭하여 빌드 설정을 변경해줄 것이다.
Modify options
를 클릭하고,On frame deactivation
에 들어가서Update resources
를 선택한다.
위와 같이 설정을 하면 실행하고 있는 Spring Boot 어플리케이션이 대기하고 있는 동안 변경사항이 있을 경우 resources를 업데이트 해준다. 템플릿 내부의 내용을 변경하면 서버 재시작 없이 잠깐의 대기 후에 변경내용이 반영되는 것을 볼 수 있다.
약간의 문제
아마도 레지스트리 값의 문제라고 생각하는데, 변경 사항이 반영되면서 서버가 두 번 재시작하는 경우가 있다. 아직은 레지스트리 값을 제대로 이해하고 있지 못하니, 추후 조금 더 알아봐서 레지스트리 값의 스윗 스팟을 찾아보는 편이 좋을 것 같다.
끝.