Retain existing modules in JacksonAutoConfiguration

Previously, the default Jackson2ObjectMapperBuilderCustomizer
implementation did set the list of modules to use. This had the effect
of removing any modules that were registered programmatically by a
customizer with higher precedence.

This commit uses the variant of modulesToInstall that retain any
existing modules. It also adds a note in the documentation as this
behavior can be easily missed.

See gh-42836
This commit is contained in:
Dmytro Nosan
2024-10-22 23:54:56 +03:00
committed by Stéphane Nicoll
parent ff6c7c7fdf
commit 993fbb3a0d
2 changed files with 24 additions and 1 deletions

View File

@@ -307,7 +307,7 @@ public class JacksonAutoConfiguration {
}
private void configureModules(Jackson2ObjectMapperBuilder builder) {
builder.modulesToInstall(this.modules.toArray(new Module[0]));
builder.modulesToInstall((modules) -> modules.addAll(this.modules));
}
private void configureLocale(Jackson2ObjectMapperBuilder builder) {

View File

@@ -73,6 +73,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import static org.assertj.core.api.Assertions.assertThat;
@@ -324,6 +326,16 @@ class JacksonAutoConfigurationTests {
});
}
@Test
void customModulesRegisteredByBuilderCustomizerWithHighestPrecedenceShouldBeRetained() {
this.contextRunner.withUserConfiguration(ModuleConfig.class, CustomModuleBuilderCustomizerConfig.class)
.run((context) -> {
ObjectMapper objectMapper = context.getBean(Jackson2ObjectMapperBuilder.class).build();
assertThat(context.getBean(CustomModule.class).getOwners()).contains(objectMapper);
assertThat(objectMapper.getRegisteredModuleIds()).contains("customizer-module");
});
}
@Test
void defaultSerializationInclusion() {
this.contextRunner.run((context) -> {
@@ -592,6 +604,17 @@ class JacksonAutoConfigurationTests {
}
@Configuration(proxyBeanMethods = false)
static class CustomModuleBuilderCustomizerConfig {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
Jackson2ObjectMapperBuilderCustomizer customModuleCustomizer() {
return (builder) -> builder.modulesToInstall(new SimpleModule("customizer-module"));
}
}
@Configuration(proxyBeanMethods = false)
static class ObjectMapperBuilderConsumerConfig {