Spring Boot 3.5 핵심 변경 사항

Spring Boot 3.5는 3.4에서 도입된 구조화 로깅을 발전시키고, SSL 설정 간소화, WebClient 글로벌 설정, GraalVM 네이티브 이미지 최적화를 중심으로 업데이트되었다. 2026년 4월 현재 3.5.13까지 패치가 진행되고 있다.

1. 구조화 로깅 (Structured Logging)

Spring Boot 3.4에서 도입된 구조화 로깅은 3.5에서 더욱 안정화되었다. 로그를 JSON 형태로 출력하여 ELK, Datadog 등 로그 분석 도구와 쉽게 연동할 수 있다.

ECS(Elastic Common Schema) 형식

# application.yml
logging:
  structured:
    format:
      console: ecs
      file: logstash
  file:
    name: ./logs/app.log

위 설정만으로 콘솔에는 ECS 형식, 파일에는 Logstash 형식으로 로그가 출력된다.

// 출력 예시 (ECS 형식)
{
  "@timestamp": "2026-04-09T14:30:00.000Z",
  "log.level": "INFO",
  "message": "사용자 로그인 성공",
  "service.name": "user-service",
  "service.version": "1.0.0",
  "process.pid": 12345,
  "ecs.version": "1.2.0"
}

커스텀 필드 추가

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

@RestController
public class UserController {
    private static final Logger log = 
        LoggerFactory.getLogger(UserController.class);
    
    @PostMapping("/login")
    public ResponseEntity login(
            @RequestBody LoginRequest request) {
        // MDC로 구조화 로그에 컨텍스트 추가
        MDC.put("userId", request.getUserId());
        MDC.put("action", "LOGIN");
        MDC.put("clientIp", getClientIp());
        
        try {
            authService.authenticate(request);
            log.info("사용자 로그인 성공");
            return ResponseEntity.ok("success");
        } catch (AuthException e) {
            log.warn("로그인 실패: {}", e.getMessage());
            return ResponseEntity.status(401).body("fail");
        } finally {
            MDC.clear();
        }
    }
}

2. WebClient 글로벌 설정

Spring Boot 3.5에서 WebClient의 타임아웃, 리다이렉트 등을 properties 파일로 글로벌 설정할 수 있게 되었다.

# application.yml
spring:
  http:
    client:
      connect-timeout: 5s
      read-timeout: 30s
      redirects: follow
      max-redirects: 5
      ssl:
        bundle: my-client-ssl

커스텀 빌더 설정

@Configuration
public class WebClientConfig {
    
    @Bean
    public WebClient webClient(
            WebClient.Builder builder,
            ClientHttpConnectorBuilder connectorBuilder) {
        
        // ClientHttpConnectorBuilder로 세밀한 설정
        var connector = connectorBuilder
            .withCustomizer(httpClient -> httpClient
                .option(ChannelOption.SO_KEEPALIVE, true)
                .responseTimeout(Duration.ofSeconds(10))
            )
            .build();
        
        return builder
            .clientConnector(connector)
            .baseUrl("https://api.example.com")
            .defaultHeader("X-API-Version", "v2")
            .filter(ExchangeFilterFunctions
                .basicAuthentication("user", "pass"))
            .build();
    }
}

3. SSL 자동 설정

Spring Boot 3.5에서는 Testcontainers와 Docker Compose 통합에 클라이언트 측 SSL이 자동 지원된다.

# SSL 번들 정의
spring:
  ssl:
    bundle:
      pem:
        my-client-ssl:
          keystore:
            certificate: classpath:client.crt
            private-key: classpath:client.key
          truststore:
            certificate: classpath:ca.crt
      jks:
        server-ssl:
          keystore:
            location: classpath:keystore.jks
            password: changeit
          truststore:
            location: classpath:truststore.jks
            password: changeit

# 데이터소스에 SSL 적용
  datasource:
    url: jdbc:postgresql://db.example.com:5432/mydb
    ssl:
      bundle: my-client-ssl

Testcontainers SSL 통합

@SpringBootTest
@Testcontainers
class SecureDbTest {
    
    @Container
    @ServiceConnection
    static PostgreSQLContainer postgres = 
        new PostgreSQLContainer<>("postgres:17")
            .withSsl(true);  // SSL 자동 구성
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Test
    void sslConnectionWorks() {
        String sslUsed = jdbcTemplate.queryForObject(
            "SHOW ssl", String.class
        );
        assertThat(sslUsed).isEqualTo("on");
    }
}

4. Actuator 보안 강화

heapdump 엔드포인트의 기본 접근 수준이 NONE으로 변경되었다. 민감 정보 유출을 방지하기 위한 조치이다.

# heapdump 사용 시 명시적 설정 필요
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,heapdump
  endpoint:
    heapdump:
      access: RESTRICTED  # 명시적 허용 필요
    health:
      show-details: when-authorized
      
# 보안 설정
@Configuration
public class ActuatorSecurity {
    @Bean
    public SecurityFilterChain actuatorSecurity(
            HttpSecurity http) throws Exception {
        return http
            .securityMatcher("/actuator/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/actuator/health")
                    .permitAll()
                .requestMatchers("/actuator/heapdump")
                    .hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults())
            .build();
    }
}

5. GraalVM 네이티브 이미지 최적화

Spring Boot 3.5에서 GraalVM 네이티브 이미지 빌드가 더 빨라지고 호환성이 개선되었다.

<!-- pom.xml -->
<plugin>
    <groupId>org.graalvm.buildtools</groupId>
    <artifactId>native-maven-plugin</artifactId>
    <configuration>
        <buildArgs>
            <arg>--gc=G1</arg>
            <arg>-O2</arg>
            <arg>--strict-image-heap</arg>
        </buildArgs>
    </configuration>
</plugin>
# 네이티브 이미지 빌드
./mvnw -Pnative native:compile

# 실행 시간 비교
# JVM:     Started in 2.3 seconds
# Native:  Started in 0.08 seconds

6. ConfigurationProperties 검증 개선

@ConfigurationProperties(prefix = "app")
@Validated
public record AppConfig(
    @NotBlank String name,
    @Min(1) @Max(65535) int port,
    @Valid DatabaseConfig database  // @Valid로 중첩 검증 활성화
) {
    public record DatabaseConfig(
        @NotBlank String url,
        @NotBlank String username,
        @Min(1) @Max(100) int maxPoolSize
    ) {}
}
# application.yml
app:
  name: my-service
  port: 8080
  database:
    url: jdbc:postgresql://localhost:5432/mydb
    username: admin
    max-pool-size: 20

Spring Boot 3.5는 운영 환경의 보안과 관측 가능성(Observability)을 크게 향상시켰다. 구조화 로깅과 SSL 자동 설정은 즉시 적용할 수 있는 실용적 개선이므로 기존 3.4 사용자라면 업그레이드를 적극 검토하자.