Skip to content
메모장
Go back

Spring Boot 4 + Jackson 3 — Redis 직렬화가 조용히 어긋나는 지점

개요

Spring Boot 4는 기본 ObjectMapper를 Jackson 3(tools.jackson) 기반 JsonMapper로 바꿨다.

JacksonAutoConfiguration(source) 참고

import tools.jackson.databind.json.JsonMapper; // com.fasterxml.jackson이 아니다

@Bean
@Primary
JsonMapper jacksonJsonMapper(JsonMapper.Builder builder) { ... }

@Primary가 붙은 기본 ObjectMapper 격인 Bean이 정확히 tools.jackson.databind.json.JsonMapper 타입이다. 커스텀 직렬화 설정을 넣으려면 이제 JsonMapperBuilderCustomizer(Jackson 3, 같은 패키지)를 구현해야 한다.


1. Redis 캐시 직렬화 — GenericJackson2JsonRedisSerializer는 이제 deprecated

Spring Data Redis의 GenericJackson2JsonRedisSerializer(Jackson 2 기반)는 Boot 4부터 deprecated(forRemoval)다.

/**
 * Spring Boot 4는 Jackson3(tools.jackson) 기반 JsonMapper를 기본 ObjectMapper로 쓴다
 * (spring-boot-jackson의 JacksonAutoConfiguration#jacksonJsonMapper 참고). 그래서 캐시 값
 * 직렬화도 Jackson3용 GenericJacksonJsonRedisSerializer를 사용한다 — Jackson2 기반
 * GenericJackson2JsonRedisSerializer는 4.0부터 deprecated(forRemoval)이다.
 */
@Configuration
@EnableCaching
class CacheConfig {
    companion object {
        fun createValueSerializer(): GenericJacksonJsonRedisSerializer {
            val typeValidator = BasicPolymorphicTypeValidator.builder()
                .allowIfSubType("com.gachi.")
                .allowIfSubType("java.util.")
                .allowIfSubType("java.lang.")
                .allowIfSubType("kotlin.")
                .build()

            return GenericJacksonJsonRedisSerializer.builder()
                .enableDefaultTyping(typeValidator)
                .build()
        }
    }
}

builder()가 호출마다 독립된 JsonMapper.Builder를 새로 만들기 때문에, 앱 전역 JsonMapper 빈을 공유/변경하지 않고 캐시 전용 ObjectMapper를 격리해서 쓸 수 있다는 것도 이 방식의 장점이다.

enableDefaultTyping(typeValidator)는 역직렬화 시 타입 정보를 값 안에 함께 저장해서(@class 메타데이터 형태) 다형성을 지원한다.

이 시리얼라이저는 나중에 회원탈퇴 기능의 재가입 차단 마커(WithdrawMarker/WithdrawPayload)를 저장하는 redisJsonTemplate에도 그대로 재사용했다

이 프로젝트의 JacksonSerializationConfig(Instant 커스텀 직렬화 모듈 추가용)도 실제로 확인해보니 tools.jackson.* 기준으로 정확히 JsonMapperBuilderCustomizer를 구현하고 있었다 — Jackson 2/3 이름이 비슷한 인터페이스가 섞여 있어서 자칫 헷갈리기 쉬운데, 다행히 이 프로젝트는 처음부터 맞게 되어 있었다.


2. Boolean 프로퍼티(isXxx) 직렬화 어긋남 주의

Jackson 3의 실제 ObjectMappertools.jackson이라는 걸 놓치면, isXxx 형태의 Boolean 프로퍼티에서 직렬화/역직렬화 시 필드명이 어긋날 수 있다.

캐싱 대상 타입에 이런 프로퍼티가 있으면 실제 캐시 적중/직렬화 여부를 테스트로 반드시 확인해야 한다


요약

항목Boot 4 이전Boot 4 이후
기본 ObjectMapperJackson 2 (com.fasterxml.jackson)Jackson 3 (tools.jackson)
Redis 캐시 직렬화GenericJackson2JsonRedisSerializerGenericJacksonJsonRedisSerializer (Jackson2 버전은 deprecated)
Boolean 프로퍼티(isXxx)-직렬화 필드명이 어긋날 수 있어 캐싱 대상이면 실제 테스트 필요

Jackson 2 → 3 전환은 컴파일 에러로 안 잡히는 게 제일 위험하다


Share this post:

Previous Post
DB 3 value logic - 가격 협의 게시글이 필터에서 사라지던 이유
Next Post
@TransactionalEventListener(AFTER_COMMIT) 제대로 쓰기 — 캐시 무효화부터 예외를 삼키는 함정까지