반응형
Jake Seo
제이크서 위키 블로그
Jake Seo
전체 방문자
오늘
어제
  • 분류 전체보기 (715)
    • 일상, 일기 (0)
    • 백준 문제풀이 (1)
    • 릿코드 문제풀이 (2)
    • 알고리즘 이론 (10)
      • 기본 이론 (2)
      • 배열과 문자열 (8)
    • 데이터베이스 (15)
      • Planet Scale (1)
      • MSSQL (9)
      • 디비 기본 개념 (1)
      • SQLite 직접 만들어보기 (4)
    • 보안 (7)
    • 설계 (1)
    • 네트워크 (17)
      • HTTP (9)
      • OSI Layers (5)
    • 회고 (31)
      • 연간 회고 (2)
      • 주간 회고 (29)
    • 인프라 (52)
      • 도커 (12)
      • AWS (9)
      • 용어 (21)
      • 웹 성능 (1)
      • 대규모 서비스를 지탱하는 기술 (9)
    • 깃 (7)
    • 빌드 도구 (7)
      • 메이븐 (6)
      • 그레이들 (0)
    • Java (135)
      • 이펙티브 자바 (73)
      • 자바 API (4)
      • 자바 잡지식 (30)
      • 자바 디자인 패턴 (21)
      • 톰캣 (Tomcat) (7)
    • 프레임워크 (64)
      • next.js (14)
      • 스프링 프레임워크 (28)
      • 토비의 스프링 (6)
      • 스프링 부트 (3)
      • JPA (Java Persistence API) (5)
      • Nest.js (8)
    • 프론트엔드 (48)
      • 다크모드 (1)
      • 노드 패키지 관리 매니저 (3)
      • CSS (19)
      • Web API (11)
      • tailwind-css (1)
      • React (5)
      • React 새 공식문서 요약 (1)
      • HTML (Markup Language) (5)
    • 자바스크립트 (108)
      • 모던 자바스크립트 (31)
      • 개념 (31)
      • 정규표현식 (5)
      • 코드 스니펫 (1)
      • 라이브러리 (6)
      • 인터뷰 (24)
      • 웹개발자를 위한 자바스크립트의 모든 것 (6)
      • 팁 (2)
    • Typescript (49)
    • 리눅스와 유닉스 (10)
    • Computer Science (1)
      • Compiler (1)
    • IDE (3)
      • VSCODE (1)
      • IntelliJ (2)
    • 세미나 & 컨퍼런스 (1)
    • 용어 (개발용어) (16)
      • 함수형 프로그래밍 용어들 (1)
    • ORM (2)
      • Prisma (2)
    • NODEJS (2)
    • cypress (1)
    • 리액트 네이티브 (React Native) (31)
    • 러스트 (Rust) (15)
    • 코틀린 (Kotlin) (4)
      • 자바에서 코틀린으로 (4)
    • 정규표현식 (3)
    • 구글 애널리틱스 (GA) (1)
    • SEO (2)
    • UML (2)
    • 맛탐험 (2)
    • 리팩토링 (1)
    • 서평 (2)
    • 소프트웨어 공학 (18)
      • 테스팅 (16)
      • 개발 프로세스 (1)
    • 교육학 (1)
    • 삶의 지혜, 통찰 (1)
    • Chat GPT (2)
    • 쉘스크립트 (1)
    • 컴파일 (2)
    • Dart (12)
    • 코드팩토리의 플러터 프로그래밍 (4)
    • 플러터 (17)
    • 안드로이드 스튜디오 (1)
    • 윈도우즈 (1)
    • 잡다한 백엔드 지식 (1)
    • 디자인 패턴 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 객체복사
  • bean Validation
  • 슬로우 쿼리
  • MSSQL
  • 메이븐 페이즈
  • 토비의 스프링
  • 자료구조
  • 이펙티브 자바
  • next js app
  • 외래키 제약조건
  • 자바스크립트 인터뷰
  • 플라이웨이트패턴
  • item8
  • 싱글톤
  • 작업기억공간
  • item7
  • try-with-resources
  • 이펙티브자바
  • pnpm
  • 프로그래머의 뇌
  • 추상 팩터리 패턴
  • 메이븐 라이프사이클
  • Java
  • 참조 해제
  • 서버리스 컴퓨팅
  • NEXT JS
  • rust
  • 디자인패턴
  • 싱글톤 패턴
  • 스프링 검증
  • Next.js
  • serverless computing
  • prerendering
  • 자바
  • 자바스크립트
  • Pre-rendering
  • 빈 검증
  • 알고리즘
  • 자바 디자인패턴
  • 메이븐 골
  • 느린 쿼리
  • 자바 검증
  • 싱글턴
  • item9
  • 도커공식문서
  • 팩터리 메서드 패턴
  • 이펙티브 자바 item9
  • 자바스크립트 면접
  • 러스트
  • Javadoc 자바독 자바주석 주석 Comment

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Jake Seo

제이크서 위키 블로그

프레임워크/스프링 프레임워크

스프링부트 개발도구(spring-boot-devtools) 정리

2022. 3. 31. 09:52

소개

스프링부트 개발을 더욱 쾌적하게 해주는 도구이다. 대표적인 기능으로는 다음과 같은 기능이 있다.

  • 스프링 부트 Restart: 재시작 시간을 단축해준다.
  • 자동 재시작: 클래스 패스에 있는 파일이 변경되었을 때, 자동으로 애플리케이션을 재시작한다.
  • LiveReload: 리소스 변경사항을 브라우저에 즉각 반영해준다.
  • 캐시 무효화: 디폴트 설정으로 동작하는 캐싱 기능들을 꺼준다.

공식 문서

Restart vs Reload

스프링부트는 재시작할 때 2개의 클래스 로더를 사용한다. base classloader 와 restart classloader 가 있다. 서드파티 라이브러리와 같은 변하지 않는 클래스는 base classloader 에 로드되고, 내가 현재 개발하는 클래스들은 restart classloader 에 로드된다. 애플리케이션이 재시작되면 restart classloader 가 던져지고, 새로운 restart classloader 가 만들어진다. 이 방식은 그냥 시작하는 "cold starts" 보다는 일반적으로 훨씬 빠르다. 왜냐하면 base classloader 는 바뀔 필요가 없기 때문이다.

JRebel from ZeroTurnaround와 같은 기술을 이용하면 훨씬 빠르게 재시작이 가능하다. 클래스가 로드될 때 재작성함으로써 새로 고침을 더 쉽게 할 수 있다.

클래스 로딩 이슈 진단

  • 스프링 부트의 Restart 기능은 대부분의 프로젝트에서는 잘 동작하지만, 멀티 모듈 프로젝트에서 클래스 로딩 이슈를 일으킬 때도 있다.
  • 그럴 땐 아래의 설명을 읽고 Restart를 끄거나, Restart 클래스 로더를 커스터마이징하면 된다.

Restart(재시작) 비활성화하기

  • 위에서 언급한 스프링 부트의 Restart(재시작) 기능을 끄고 싶다면, application.properties에서 spring.devtools.restart.enabled를 이용해 끌 수 있다.
    • 여전히 restart classloader 는 동작하지만, 파일 변화 감지는 안 한다.
  • 완전히 Restart 기능을 끄고 싶다면, 스프링부트 앱이 시작되기 전에 아래와 같이 시스템 프로퍼티를 설정해야 한다.
@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(MyApplication.class, args);
    }

}

Restart 클래스 로더 커스터마이징

  • META-INF/spring-devtools.properties 파일을 작성함으로써, restart classloader 에 뺄 것과 넣을 것을 정할 수도 있다.
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\\.]+\\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\\.]+\\.jar

캐싱 무효화

템플릿 엔진은 파싱된 템플릿 파일을 이용하고, 스프링 MVC는 정적 리소스를 서빙할 때 캐싱 헤더를 추가한다. 캐싱은 프로덕션에서는 많은 이익을 주지만, 개발 단계에서는 생산성을 떨어트릴 수 있다. spring-boot-devtools 는 여러가지 캐싱을 기본적으로 꺼둔다.

세부사항 참고 공식문서

참고 - 캐싱 무효화를 사용하기 싫다면?

application.properties에서 spring.devtools.add-properties의 값을 false로 하면 기본 설정값을 사용하지 않을 수 있다.

자동 재시작

클래스 패스에 있는 파일이 변경될 때마다 애플리케이션이 재시작된다. 빠른 피드백 루프를 제공해줄 수 있다. 기본적으로, 디렉토리를 가리키는 클래스 패스 엔트리 변화를 모니터링한다. 정적 자원, 뷰 템플릿과 같은 리소스들은 재시작이 필요 없다.

참고 - 제외 리소스 (Excluding Resources)

/META-INF/maven, /META-INF/resources, /resources, /static, /public, /templates 과 같은 디렉토리에 있는 리소스들을 바꾸었다면, 재시작을 할 필요 없이 Live Reload 하면 된다.

만일 이러한 제외 리소스들을 커스터마이징하고 싶다면, application.properties에 아래의 속성을 추가하면 된다.

spring.devtools.restart.exclude=static/**,public/**

만일 기본 값은 유지하면서 추가적으로 제외 리소스를 추가하고 싶다면 spring.devtools.restart.additional-exclude를 대신 쓰면 된다.

재시작 Triggering 하기

devtools 는 클래스 패스 리소스를 모니터링한다. 클래스 패스를 업데이트 하기 위해서는 어떤 IDE를 사용하냐에 따라 다르다.

  • IntellijIDEA 에서는 프로젝트를 빌드하면 된다. (Build > Build Project)
  • 빌드 플러그인을 사용하면, mvn compile, gradle build 명령어를 이용하자.
    • 빌드 플러그인을 이용하려면 forking을 enable 상태로 두어야 한다.

로그 리포트 끄기

spring.devtools.restart.log-condition-evaluation-delta=false
  • 재시작 시에 condition evaluation delta 로그를 끈다.
    • 위 로그는 스프링 부트 auto-configuration 에서의 변경사항을 나타내는 로그이다.

추가 경로 watch 하기

  • 클래스 패스 외에 다른 경로를 watch 하고 싶다면 설정한다.
  • spring.devtools.restart.additional-paths를 application.properties에 등록하고 이용하면 된다.

트리거 파일 만들어서 재시작하기

만일 매번 클래스 패스 파일이 변경될 때마다 재시작되는 것이 싫다면, 트리거 파일 하나를 두고 그 파일이 바뀔 때 재시작할 수도 있다.

src
+- main
   +- resources
      +- .reloadtrigger

위 경로에 넣어주면 된다.

spring.devtools.restart.trigger-file=.reloadtrigger

src/main/resources/.reloadtrigger 파일이 업데이트되면 재시작된다.

IDE restart 지원

Intellij 공식 문서를 참고하여, restart 시점을 맘대로 정할 수 있다.

Live Reload

자동 재시작이 활성화된 상태에서 LiveReload 를 이용할 수 있다. spring-boot-devtools 모듈은 리소스가 변경되었을 때, 브라우저를 새로고침하는 내장된 LiveReload 서버를 포함한다. LiveReload 브라우저 익스텐션은 Chrome, Firefox, Safari 에서 이용 가능하다.

LiveReload 서버는 한번에 하나만 구동 가능하다. 앱을 시작하기 전에 다른 LiveReload 서버가 동작중이지 않은 것을 확실히 체크하자. IDE에서 여러 애플리케이션을 시작하면, 첫번째만 LiveReload 서버가 지원된다.

JRebel을 이용하면, automatic restart는 꺼지니 주의하자. 대신 나머지는 잘 동작한다.

주의사항들

역직렬화에 관련된 이슈

표준 ObjectInputStream에 의해 역직렬화되는 오브젝트들이 있을 때 Restart 기능을 사용하면 잘 동작하지 않는다. 이럴 때는 ConfigurableObjectInputStream를 Thread.currentThread().getContextClassLoader()와 함께 사용할 필요가 있을 수 있다.

몇몇 서드파티 라이브러리들은 context classloader를 고려하지 않고 역직렬화를 한다. 만일 이러한 문제를 발견했다면, 작성자에게 수정을 요청하자.

프로덕션 동작과 관련된 주의점

  • spring-boot-devtools는 프로덕션에서는 비활성화 된다.
    • java-jar와 같은 명령어로 실행된 애플리케이션은 프로덕션 레벨에서 실행됐다고 보아 spring-boot-devtools가 비활성화된다.
  • VM 옵션에 -Dspring.devtools.restart.enabled=true를 줘서 프로덕션 레벨에서도 켤 수 있다.
  • 프로덕션 레벨에서 spring-boot-devtools를 켜면 보안상의 취약점이 생길 수 있으니 절대 켜면 안된다.
    • -Dspring.devtools.restart.enabled=false로 확실히 끌 수 있다.

Gradle Configuration을 지키자

  • gradle에서 developmentOnly 설정으로 적용하자.
    • 프로젝트를 사용하는 다른 모듈에게 '과도적(transitively)'으로 사용되지 않기 위해서이다.
  • 재패키징된 아카이브는 devtools를 기본으로 포함하지 않는다.
    • 원격 devtools 기능

AspectJ weaving과 관련된 주의사항

AspectJ weaving 을 사용하면 Automatic restart 는 적용되지 않는다.

반응형
저작자표시 (새창열림)

'프레임워크 > 스프링 프레임워크' 카테고리의 다른 글

DispatchServlet.doDispatch() 함수 끝까지 따라가서 HandlerMapping 과 HandlerAdapter 알아보기  (0) 2023.01.30
스프링 객체 검증 (Validation) 적용하기  (0) 2022.05.29
asciidoctor 를 통한 Spring REST Docs 자동 생성 세팅하기  (2) 2022.05.18
Spring REST Docs + asciidoctor 로 문서 자동 생성해보기  (0) 2022.05.15
AutoConfigureMockMvc 에서 한글이 제대로 인식되지 않을 때  (0) 2022.04.03
    '프레임워크/스프링 프레임워크' 카테고리의 다른 글
    • 스프링 객체 검증 (Validation) 적용하기
    • asciidoctor 를 통한 Spring REST Docs 자동 생성 세팅하기
    • Spring REST Docs + asciidoctor 로 문서 자동 생성해보기
    • AutoConfigureMockMvc 에서 한글이 제대로 인식되지 않을 때
    Jake Seo
    Jake Seo
    ✔ 잘 보셨다면 광고 한번 클릭해주시면 큰 힘이 됩니다. ✔ 댓글로 틀린 부분을 지적해주시면 기분 나빠하지 않고 수정합니다. ✔ 많은 퇴고를 거친 글이 좋은 글이 된다고 생각합니다. ✔ 간결하고 명료하게 사람들을 이해 시키는 것을 목표로 합니다.

    티스토리툴바