DevTools
탄생 배경 - 애플리케이션 시간 단축
애플리케이션에 코드 변경사항을 반영하기 위해 재시작을 했다
스프링 프레임워크는 애플리케이션 서버(ex:Java EE) 대신 서블릿 컨테이너를 선택해서 재시작 문제 해결을 시도했다
그러다 2014년 스프링 부트가 처음 출시되면서 내장형 서블릿 컨테이너라는 혁신을 이루었다
스프링 프레임워크는 서블릿 컨테이너에 애플리케이션을 배포하는 형식이라 서블릿 컨테이너에 종속된다
하지만 스프링 부트는 애플리케이션에 서블릿 컨테이너를 포함하는 방식으로
애플리케이션 시작 속도를 높인 것뿐만 아니라 더 이상 서블릿 컨테이너에 종속되지 않아
애플리케이션 배포 자체를 뒤바꿔버렸다
그러나 스프링 부트 개발팀은 내장형 서블릿 컨테이너로 애플리케이션 시간 단축에 만족하지 않았다
그래서 애플리케이션을 더 빨리 실행할 수 있는 개선 방법을 탐구하다
DevTools라는 새로운 개발자 도구를 만들어냈다
[참고]
https://zepinos.tistory.com/35
DevTools의 주요 기능
- 애플리케이션 재시작(restart)과 리로드(reload) 자동화
- 환경설정 정보 기본값 제공
- 자동설정(autoconfiguration) 변경사항 로깅
- 정적 자원 제외
- 라이브 리로드(LiveReload) 지원
사용 하기
devtools는 프로덕션 환경에서는 수행해서는 안된다.
프로젝트에서 DevTools 개발자 도구를 사용하려면 빌드 파일에 의존 관계를 추가해야 한다
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools
위의 문서와 책에 보면 maven기준 optional을 true로 지정했다
지정한 이유는 추가한 선택적 의존 관계는 실제 상용 운영 코드에는 추가되지 않기 때문에 모듈에 대한 의존관계가 의도하지 않게 외부로 전파되는 것을 막아준다
spring-boot-devtools의 개발자 도구의 모든 기능 활성화
spring-boot-devtools는 애플리케이션 시작 방법을 몰래 훔쳐본다
java -jar 명령이나 클라우드 서비스 제공자가 사용하는 클래스로더를 통해 애플리케이션이 실행되면
훔쳐보던 spring-boot-devtools가 이번 실행은 상용이구나라고 판단하고 개발자 도구 기능을 활성화하지 않는다
하지만 애플리케이션이 IDE에서 실행되거나 메이븐의 spring-boot:run 명령으로 실행되면, 개발 모드라고 판단하고 개발자 도구의 모든 기능을 활성화한다
단 다중 모듈의 경우 클래스 로딩 문제를 일으킬 수 있다
Diagnosing Classloading Issues은 이를 진단하고 해결하는 방법을 알려준다
자동 재시작과 리로딩
스프링 부트 개발팀은 사용자 코드 변화를 감지하고 애플리케이션을 재시작하는 기능을 추가했다
스프링 부트가 제공하는 재시작은 두 개의 클래스 로더를 사용하여 작동한다
변경되지 않는 클래스(예를 들면 서드파티 라이브러리)는 기본 클래스로더(base classloader)에 로딩되고,
개발자가 작성한 코드는 재시작 클래스로더(restart classloader)에 로딘된다
애플리케이션이 재시작이 되면 restart classloader는 삭제되고 새로운 클래스로더가 사용됩니다
이렇게 restart classloader만 새로 리로드하면 모든 것을 새로 시작하는 콜드(cold)시작 방식보다
훨씬 빨리 애플리케이션을 재시작할 수 있다
하지만 스프링 부트에는 한계도 있다.
리로드 개선 효과를 최대로 끌어내려면 제이레블(JRebel)같은 자바 에이전트 솔루션이 필요할 수 있다
애플리케이션 자동 재시작
공식 문서에 따르면 트리거 파일을 사용하여 재시작해야 한다고 되어있으나
이클립스나 인텔리제이는 트리거 파일을 사용하지 않고도 되는 기능이 있다고 나와있다
(인텔리제이의 경우 문서 지침을 따를 수 있다고 나와있다)
책에서는 애플리케이션 자동 재시작이 제대로 동작하는지 아래처럼 확인해보라고 나와있다
- IDE에서 저장 명령이나 빌드 프로젝트 명령을 실행해서 스프링 부트에게 재시작하라는 신호를 보낸다
- 콘솔 출력을 모니터링해서 애플리케이션 재시작이 동작하는지 확인한다
이클립스에서는 저장 명령이 재시작을 유발하고, 인텔리제이에서는 빌드 프로젝트 명령이 재시작을 유발한다고 되어있다
인텔리제이에서 재시작하기 위해선 아래의 옵션을 설정한다
정적 자원 제외
- /META-INF/maven
- /META-INF/resources
- /resources
- /static
- /public
- /templates
스프링 부트는 정적 자원 변경이 발생해도 재시작을 하지 않는다
대부분 웹 기술에서는 정적 자원 변경 내용은 재부팅 없어도 서버에 반영할 수 있기 때문이다
변경사항이 재시작을 유발하지 않게 하는 경로를 변경하려면 다음과 같이 설정하면 된다
spring:
devtools:
restart:
exclude: "static/**,public/**"
개발자 도구 비활성화
spring.devtools.restart.enabled=false
위와 같이 설정하면 개발자 도구에 의한 재시작 자체를 아예 비활성화할 수 있다
개발 모드에서 캐시 비활성화
spring:
thymeleaf:
cache: false
위와 같이 설정하면 타임리프 캐시 기능을 비활성화할 수 있다
라이브 리로드 지원
스프링 부트 개발자 도구에는 라이브 리로드 서버가 내장돼 있다
라이브 리로드는 서버가 재시작됐을 때 웹 페이지를 새로 로딩하는 단순한 작업을 수행한다
'IT > 기록' 카테고리의 다른 글
gradle project에서 JMH 라이브러리를 이용해 java code 성능 측정 (0) | 2022.08.03 |
---|---|
사용자 입력이 필요한 JUnit Test (0) | 2022.07.19 |
[Error] Set the spring.mongodb.embedded.version property or define your own MongodConfig bean to use embedded MongoDB (0) | 2022.06.29 |
Flutter I/O Extended Korea 2022에 다녀오다! (0) | 2022.06.28 |
[Flutter] 마스코트 귀여운 새! 이름은 무엇인가? (0) | 2022.06.27 |