Contents
see ListSpring Boot 3.4 주요 변경사항 개요
2024년 11월 출시된 Spring Boot 3.4는 Virtual Threads 통합 강화, 관찰 가능성(Observability) 개선, GraalVM Native Image 지원 확대를 핵심으로 한다. 특히 Spring AI와의 통합이 주목받고 있으며, 2025년에는 Spring Boot 4.0 마이그레이션 경로와 함께 Spring AI 2.0 마일스톤 버전이 공개되었다.
Virtual Threads 활성화 및 최적화
Spring Boot 3.2부터 지원한 Virtual Threads 통합이 3.4에서 더욱 성숙해졌다. 이제 OtlpMeterRegistry와 Undertow 웹 서버도 Virtual Threads를 활용한다.
# application.yml
spring:
threads:
virtual:
enabled: true
# Tomcat 최대 스레드 수 - 가상 스레드 환경에서는 높게 설정 가능
server:
tomcat:
threads:
max: 10000 # 가상 스레드이므로 메모리 부담 없음// Virtual Thread 기반 TaskExecutor 명시적 설정
@Configuration
public class AsyncConfig {
@Bean
public TaskExecutor taskExecutor() {
return new VirtualThreadTaskExecutor("my-task-");
}
@Bean
public AsyncTaskExecutor applicationTaskExecutor() {
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor("async-");
executor.setVirtualThreads(true);
return executor;
}
}
// @Async 어노테이션과 함께 사용
@Service
public class ReportService {
@Async
public CompletableFuture generateReport(Long reportId) {
// 가상 스레드에서 실행됨
Report report = buildReport(reportId); // 블로킹 I/O 포함
return CompletableFuture.completedFuture(report);
}
} Spring AI: LLM 통합의 표준
Spring AI는 OpenAI, Anthropic, Google Gemini, Ollama 등 다양한 LLM 제공자를 일관된 API로 사용할 수 있게 해주는 프레임워크다. 2025년 초 Anthropic과 함께 MCP(Model Context Protocol) Java SDK 공식 개발을 주도하면서 AI 에이전트 개발의 핵심 라이브러리로 자리매김했다.
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-anthropic-spring-boot-starter</artifactId>
</dependency>
<!-- BOM으로 버전 관리 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement># application.yml - AI 설정
spring:
ai:
anthropic:
api-key: ${ANTHROPIC_API_KEY}
chat:
options:
model: claude-opus-4-5
max-tokens: 4096
temperature: 0.7ChatClient로 간단하게 LLM 호출
@Service
public class AIChatService {
private final ChatClient chatClient;
public AIChatService(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder
.defaultSystem("당신은 Java 전문가입니다. 명확하고 실용적인 답변을 제공하세요.")
.build();
}
// 단순 텍스트 응답
public String ask(String question) {
return chatClient.prompt()
.user(question)
.call()
.content();
}
// 구조화된 응답 (StructuredOutputConverter)
public CodeReview reviewCode(String code) {
return chatClient.prompt()
.user(u -> u.text("다음 코드를 리뷰해주세요:\n{code}").param("code", code))
.call()
.entity(CodeReview.class); // JSON 파싱 자동 처리
}
// 스트리밍 응답
public Flux askStream(String question) {
return chatClient.prompt()
.user(question)
.stream()
.content();
}
} RAG (Retrieval-Augmented Generation) 구현
Spring AI는 벡터 스토어 통합을 통해 RAG 패턴 구현을 간소화한다. pgvector, Redis, Pinecone 등 다양한 벡터 DB를 지원한다.
@Configuration
public class RAGConfig {
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel, JdbcTemplate jdbcTemplate) {
return new PgVectorStore(jdbcTemplate, embeddingModel);
}
}
@Service
public class DocumentRAGService {
private final VectorStore vectorStore;
private final ChatClient chatClient;
// 문서 인덱싱
public void indexDocument(String content, String source) {
List docs = new TokenTextSplitter().apply(
List.of(new Document(content, Map.of("source", source)))
);
vectorStore.add(docs);
}
// RAG 기반 질문 답변
public String askWithContext(String question) {
// 유사 문서 검색
List relevantDocs = vectorStore.similaritySearch(
SearchRequest.query(question).withTopK(5)
);
// 컨텍스트 생성
String context = relevantDocs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
// LLM에 컨텍스트와 함께 질문
return chatClient.prompt()
.system("다음 컨텍스트를 참고하여 질문에 답하세요:\n" + context)
.user(question)
.call()
.content();
}
} MCP (Model Context Protocol) 서버 구현
Spring AI 1.0은 MCP 서버/클라이언트 구현을 지원하여 AI 에이전트가 외부 도구를 호출할 수 있게 해준다.
@Service
public class WeatherMCPService {
// @Tool 어노테이션으로 MCP 도구 등록
@Tool(description = "특정 도시의 현재 날씨 정보를 조회합니다")
public WeatherInfo getWeather(
@ToolParam(description = "도시 이름 (예: Seoul, Tokyo)") String city) {
// 날씨 API 호출
return weatherApiClient.getCurrentWeather(city);
}
@Tool(description = "향후 7일간의 날씨 예보를 제공합니다")
public List getForecast(
@ToolParam(description = "도시 이름") String city,
@ToolParam(description = "조회할 일수 (1-7)") int days) {
return weatherApiClient.getForecast(city, days);
}
}
// MCP 서버 설정
@Configuration
public class MCPConfig {
@Bean
public ToolCallbackProvider weatherTools(WeatherMCPService weatherService) {
return MethodToolCallbackProvider.builder()
.toolObjects(weatherService)
.build();
}
} Spring Boot Actuator 개선사항
3.4에서 Actuator API가 개선되어 애플리케이션 관리가 더 편리해졌다. 새로운 /actuator/sbom 엔드포인트로 소프트웨어 BOM을 확인할 수 있으며, 헬스 그룹 및 상세 조건부 노출 기능이 강화되었다.
management:
endpoints:
web:
exposure:
include: health,info,metrics,sbom,env
endpoint:
health:
show-details: when-authorized
group:
readiness:
include: db,redis
liveness:
include: ping
health:
livenessstate:
enabled: true
readinessstate:
enabled: trueTestcontainers 통합 강화
Spring Boot 3.4의 Testcontainers 통합이 더욱 강력해졌다. 이제 서비스 연결 자동 설정(Service Connection Auto-Configuration)이 더 많은 컨테이너 타입을 지원하며, 개발 시 로컬에서 실제 데이터베이스와 메시지 브로커를 손쉽게 구동할 수 있다.
@SpringBootTest
@Testcontainers
class IntegrationTest {
@Container
@ServiceConnection // Spring Boot가 자동으로 연결 설정
static PostgreSQLContainer> postgres =
new PostgreSQLContainer<>("postgres:17-alpine");
@Container
@ServiceConnection
static RedisContainer redis = new RedisContainer("redis:8-alpine");
@Autowired
private UserRepository userRepository;
@Test
void testUserCRUD() {
User user = new User("홍길동", "hong@example.com");
User saved = userRepository.save(user);
assertThat(userRepository.findById(saved.getId())).isPresent();
}
}