Skip to content

Commit 9c5c7de

Browse files
committed
JacksonAutoConfiguration should retain modules registered in Jackson2ObjectMapperBuilderCustomizer with higher precedence, rather than overwriting them
1 parent bacd2c2 commit 9c5c7de

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -306,7 +306,7 @@ private Field findPropertyNamingStrategyField(String fieldName) {
306306
}
307307

308308
private void configureModules(Jackson2ObjectMapperBuilder builder) {
309-
builder.modulesToInstall(this.modules.toArray(new Module[0]));
309+
builder.modulesToInstall((modules) -> modules.addAll(this.modules));
310310
}
311311

312312
private void configureLocale(Jackson2ObjectMapperBuilder builder) {

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jackson/JacksonAutoConfigurationTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
import org.springframework.context.annotation.Configuration;
7474
import org.springframework.context.annotation.Import;
7575
import org.springframework.context.annotation.Primary;
76+
import org.springframework.core.Ordered;
77+
import org.springframework.core.annotation.Order;
7678
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
7779

7880
import static org.assertj.core.api.Assertions.assertThat;
@@ -324,6 +326,16 @@ void moduleBeansAndWellKnownModulesAreRegisteredWithTheObjectMapperBuilder() {
324326
});
325327
}
326328

329+
@Test
330+
void customModulesRegisteredByBuilderCustomizerWithHighestPrecedenceShouldBeRetained() {
331+
this.contextRunner.withUserConfiguration(CustomModuleJacksonBuilderCustomizerConfig.class).run((context) -> {
332+
ObjectMapper objectMapper = context.getBean(Jackson2ObjectMapperBuilder.class).build();
333+
assertThat(objectMapper.getRegisteredModuleIds()).contains("customizer-module");
334+
// must be present because the customizer has higher precedence.
335+
assertThat(objectMapper.getRegisteredModuleIds()).contains(JsonMixinModule.class.getName());
336+
});
337+
}
338+
327339
@Test
328340
void defaultSerializationInclusion() {
329341
this.contextRunner.run((context) -> {
@@ -592,6 +604,17 @@ Jackson2ObjectMapperBuilderCustomizer customDateFormat() {
592604

593605
}
594606

607+
@Configuration(proxyBeanMethods = false)
608+
static class CustomModuleJacksonBuilderCustomizerConfig {
609+
610+
@Bean
611+
@Order(Ordered.HIGHEST_PRECEDENCE)
612+
Jackson2ObjectMapperBuilderCustomizer customModuleCustomizer() {
613+
return (builder) -> builder.modulesToInstall(new SimpleModule("customizer-module"));
614+
}
615+
616+
}
617+
595618
@Configuration(proxyBeanMethods = false)
596619
static class ObjectMapperBuilderConsumerConfig {
597620

0 commit comments

Comments
 (0)