DevTools와 개발 워크플로 — 재시작 없이 빠르게 개발하는 방법
코드를 한 줄 수정할 때마다 서버를 수동으로 재시작하고 있다면, 개발 시간의 상당 부분을 낭비하고 있는 것은 아닐까요?
Spring Boot DevTools란
DevTools는 Spring Boot 개발 생산성을 높이는 도구 모음입니다. 코드 변경 시 자동 재시작, 브라우저 자동 새로고침, 개발에 적합한 기본 설정을 제공합니다.
의존성 추가
// build.gradle
dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
developmentOnly로 선언하면 배포용 JAR에 포함되지 않습니다. 운영 환경에서 DevTools가 동작할 걱정은 없습니다.
자동 재시작 (Automatic Restart)
동작 원리
DevTools는 두 개의 ClassLoader를 사용합니다.
Base ClassLoader — 라이브러리 클래스 (변경 없음, 유지)
Restart ClassLoader — 애플리케이션 클래스 (변경 시 교체)
파일이 변경되면 Restart ClassLoader만 새로 만들어서 애플리케이션 클래스를 다시 로드합니다. JVM을 재시작하지 않으므로 일반 재시작보다 훨씬 빠릅니다.
트리거 조건
IDE에서 빌드/컴파일이 수행되면 클래스 파일이 변경되어 재시작이 트리거됩니다.
- IntelliJ IDEA:
Build → Build Project(Ctrl+F9) 또는 자동 빌드 설정 - Eclipse/STS: 저장 시 자동 빌드 (기본 동작)
IntelliJ에서 자동 빌드를 활성화하려면:
Settings → Build, Execution, Deployment → Compiler
→ "Build project automatically" 체크
Settings → Advanced Settings
→ "Allow auto-make to start even if developed application is currently running" 체크
재시작 제외 설정
정적 리소스 변경에는 재시작이 필요 없습니다.
spring:
devtools:
restart:
enabled: true
# 재시작 트리거에서 제외할 경로
exclude: static/**,public/**,templates/**
# 추가 감시 경로 (클래스패스 외부)
additional-paths: src/main/resources
# 재시작 간 최소 대기 시간 (밀리초)
poll-interval: 1000
quiet-period: 400
재시작 완전 비활성화
spring:
devtools:
restart:
enabled: false
또는 시스템 프로퍼티로:
public static void main(String[] args) {
System.setProperty(
"spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
라이브 리로드 (Live Reload)
DevTools는 내장 LiveReload 서버(포트 35729)를 실행합니다. 브라우저에 LiveReload 확장 프로그램을 설치하면 서버 재시작 또는 리소스 변경 시 자동으로 브라우저가 새로고침됩니다.
spring:
devtools:
livereload:
enabled: true # 기본: true
port: 35729 # LiveReload 서버 포트
정적 리소스(HTML, CSS, JS) 변경은 서버 재시작 없이 LiveReload만 트리거됩니다.
개발용 기본 설정
DevTools가 클래스패스에 있으면 개발에 적합하도록 여러 속성이 자동 변경됩니다.
| 속성 | 기본값 | DevTools 적용값 | 이유 |
|---|---|---|---|
spring.thymeleaf.cache | true | false | 템플릿 변경 즉시 반영 |
spring.freemarker.cache | true | false | 템플릿 변경 즉시 반영 |
spring.web.resources.cache.period | - | 0 | 정적 리소스 캐시 비활성화 |
server.error.include-stacktrace | never | always | 에러 상세 정보 |
spring.h2.console.enabled | false | true | H2 Console 활성화 |
H2 Console
인메모리 DB를 웹 브라우저에서 직접 조회할 수 있는 도구입니다.
spring:
h2:
console:
enabled: true
path: /h2-console # 접속 경로
settings:
web-allow-others: false # 로컬만 접근
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
http://localhost:8080/h2-console로 접속하여 SQL을 직접 실행하고 데이터를 확인할 수 있습니다.
Spring Security와 함께 사용
@Configuration
@Profile("local")
public class LocalSecurityConfig {
@Bean
public SecurityFilterChain localFilterChain(HttpSecurity http)
throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/h2-console/**").permitAll()
.anyRequest().authenticated()
)
.csrf(csrf -> csrf
.ignoringRequestMatchers("/h2-console/**"))
.headers(headers -> headers
.frameOptions(frame -> frame.sameOrigin())) // iframe 허용
.build();
}
}
원격 디버깅
실행 중인 애플리케이션에 디버거를 연결하여 코드를 단계별로 실행할 수 있습니다.
JVM 디버그 옵션
# Java 9+
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005 \
-jar myapp.jar
Spring Boot Gradle 플러그인
./gradlew bootRun --debug-jvm
# 또는
./gradlew bootRun -Dagentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
IntelliJ 원격 디버거 설정
Run → Edit Configurations → + → Remote JVM Debug
Host: localhost
Port: 5005
개발 프로파일 활용
# application-local.yml — 개발 전용 설정
spring:
datasource:
url: jdbc:h2:mem:testdb
jpa:
show-sql: true
properties:
hibernate:
format_sql: true
hibernate:
ddl-auto: create-drop
logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
com.example: DEBUG
# 로컬 프로파일로 실행
SPRING_PROFILES_ACTIVE=local ./gradlew bootRun
Actuator 개발 활용
# application-local.yml
management:
endpoints:
web:
exposure:
include: "*" # 모든 엔드포인트 노출 (개발 전용!)
endpoint:
health:
show-details: always
유용한 엔드포인트:
/actuator/beans— 등록된 모든 빈 목록/actuator/mappings— 모든 URL 매핑/actuator/env— 환경 설정 값/actuator/configprops— @ConfigurationProperties 값/actuator/loggers— 런타임 로그 레벨 변경
개발 워크플로 최적화 팁
1. Gradle 연속 빌드
# 파일 변경 감지 시 자동 빌드
./gradlew build --continuous
2. 테스트 자동 실행
# 파일 변경 시 관련 테스트 자동 실행
./gradlew test --continuous
3. 프론트엔드 프록시
REST API 개발 시 프론트엔드 개발 서버와 연동:
# Spring Boot는 8080, React는 3000에서 실행
# React의 package.json
# "proxy": "http://localhost:8080"
4. Docker Compose 연동
# Spring Boot 3.1+ — Docker Compose 자동 관리
spring:
docker:
compose:
enabled: true
file: docker-compose-dev.yml
lifecycle-management: start-and-stop
# docker-compose-dev.yml
services:
mysql:
image: mysql:8.0
ports: ["3306:3306"]
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
redis:
image: redis:7
ports: ["6379:6379"]
Spring Boot가 시작될 때 Docker Compose를 자동으로 실행하고, 종료될 때 컨테이너를 정리합니다.
정리
- DevTools는 개발 생산성을 크게 높여줍니다.
developmentOnly로 추가하면 배포에 영향을 주지 않습니다. - 자동 재시작은 두 개의 ClassLoader로 빠르게 동작합니다. IDE의 자동 빌드 설정을 확인하세요.
- LiveReload로 브라우저 수동 새로고침을 없앨 수 있습니다.
- H2 Console은 인메모리 DB를 직접 조회하는 데 유용합니다. Security와 함께 사용할 때 설정에 주의하세요.
- 개발 프로파일(
local)을 활용하여 SQL 로깅, Actuator 노출, Docker Compose 연동 등을 설정하세요. - Spring Boot 3.1+의 Docker Compose 지원으로 개발 인프라 관리가 간편해졌습니다.