mirror of
https://github.com/spring-projects/spring-boot.git
synced 2026-10-02 15:29:05 +00:00
Automatically find and add Jackson modules
Closes gh-47485
This commit is contained in:
@@ -110,7 +110,9 @@ The context's javadoc:tools.jackson.databind.json.JsonMapper.Builder[] can be cu
|
||||
Such customizer beans can be ordered (Boot's own customizer has an order of 0), letting additional customization be applied both before and after Boot's customization.
|
||||
|
||||
Any beans of type javadoc:tools.jackson.databind.JacksonModule[] are automatically registered with the auto-configured javadoc:tools.jackson.databind.json.JsonMapper.Builder[] and are applied to any javadoc:tools.jackson.databind.json.JsonMapper[] instances that it creates.
|
||||
This provides a global mechanism for contributing custom modules when you add new features to your application.
|
||||
This provides an application-wide mechanism for contributing custom modules when you add new features to your application.
|
||||
|
||||
Any modules that participate in the Java `ServiceLoader` mechanism are, by default, found and added to the auto-configured javadoc:tools.jackson.databind.json.JsonMapper.Builder[]. To disable this behavior, set configprop:spring.jackson.find-and-add-modules[] to `false`.
|
||||
|
||||
If you want to replace the default javadoc:tools.jackson.databind.json.JsonMapper[] completely, either define a javadoc:org.springframework.context.annotation.Bean[format=annotation] of that type or, if you prefer the builder-based approach, define a javadoc:tools.jackson.databind.json.JsonMapper.Builder[] javadoc:org.springframework.context.annotation.Bean[format=annotation].
|
||||
When defining an javadoc:tools.jackson.databind.json.JsonMapper[] bean, marking it as javadoc:org.springframework.context.annotation.Primary[format=annotation] is recommended as the auto-configuration's javadoc:tools.jackson.databind.json.JsonMapper[] that it will replace is javadoc:org.springframework.context.annotation.Primary[format=annotation].
|
||||
|
||||
@@ -37,6 +37,7 @@ dependencies {
|
||||
|
||||
testImplementation(project(":core:spring-boot-test"))
|
||||
testImplementation(project(":test-support:spring-boot-test-support"))
|
||||
testImplementation("tools.jackson.module:jackson-module-kotlin")
|
||||
testRuntimeOnly("ch.qos.logback:logback-classic")
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -170,6 +170,9 @@ public final class JacksonAutoConfiguration {
|
||||
.disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS,
|
||||
DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS);
|
||||
}
|
||||
if (this.jacksonProperties.isFindAndAddModules()) {
|
||||
builder.findAndAddModules(getClass().getClassLoader());
|
||||
}
|
||||
if (this.jacksonProperties.getDefaultPropertyInclusion() != null) {
|
||||
builder.changeDefaultPropertyInclusion((handler) -> handler
|
||||
.withValueInclusion(this.jacksonProperties.getDefaultPropertyInclusion()));
|
||||
|
||||
+14
@@ -115,6 +115,12 @@ public class JacksonProperties {
|
||||
*/
|
||||
private boolean useJackson2Defaults = false;
|
||||
|
||||
/**
|
||||
* Whether to find and add modules to the auto-configured JsonMapper.Builder using
|
||||
* MapperBuilder.findAndAddModules(ClassLoader).
|
||||
*/
|
||||
private boolean findAndAddModules = true;
|
||||
|
||||
private final Datatype datatype = new Datatype();
|
||||
|
||||
private final Json json = new Json();
|
||||
@@ -199,6 +205,14 @@ public class JacksonProperties {
|
||||
this.useJackson2Defaults = useJackson2Defaults;
|
||||
}
|
||||
|
||||
public boolean isFindAndAddModules() {
|
||||
return this.findAndAddModules;
|
||||
}
|
||||
|
||||
public void setFindAndAddModules(boolean findModules) {
|
||||
this.findAndAddModules = findModules;
|
||||
}
|
||||
|
||||
public Datatype getDatatype() {
|
||||
return this.datatype;
|
||||
}
|
||||
|
||||
+18
-4
@@ -52,6 +52,7 @@ import tools.jackson.databind.json.JsonMapper;
|
||||
import tools.jackson.databind.json.JsonMapper.Builder;
|
||||
import tools.jackson.databind.module.SimpleModule;
|
||||
import tools.jackson.databind.util.StdDateFormat;
|
||||
import tools.jackson.module.kotlin.KotlinModule;
|
||||
|
||||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
|
||||
@@ -269,11 +270,11 @@ class JacksonAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
void disableMapperFeature() {
|
||||
this.contextRunner.withPropertyValues("spring.jackson.mapper.use_annotations:false").run((context) -> {
|
||||
this.contextRunner.withPropertyValues("spring.jackson.mapper.infer-property-mutators:false").run((context) -> {
|
||||
JsonMapper mapper = context.getBean(JsonMapper.class);
|
||||
assertThat(MapperFeature.USE_ANNOTATIONS.enabledByDefault()).isTrue();
|
||||
assertThat(mapper.deserializationConfig().isEnabled(MapperFeature.USE_ANNOTATIONS)).isFalse();
|
||||
assertThat(mapper.serializationConfig().isEnabled(MapperFeature.USE_ANNOTATIONS)).isFalse();
|
||||
assertThat(MapperFeature.INFER_PROPERTY_MUTATORS.enabledByDefault()).isTrue();
|
||||
assertThat(mapper.deserializationConfig().isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS)).isFalse();
|
||||
assertThat(mapper.serializationConfig().isEnabled(MapperFeature.INFER_PROPERTY_MUTATORS)).isFalse();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -591,6 +592,19 @@ class JacksonAutoConfigurationTests {
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFindAndAddModulesByDefault() {
|
||||
this.contextRunner.run((context) -> assertThat(context.getBean(JsonMapper.class).getRegisteredModules())
|
||||
.hasAtLeastOneElementOfType(KotlinModule.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotFindAndAddModulesWhenDisabled() {
|
||||
this.contextRunner.withPropertyValues("spring.jackson.find-and-add-modules=false")
|
||||
.run((context) -> assertThat(context.getBean(JsonMapper.class).getRegisteredModules())
|
||||
.doesNotHaveAnyElementsOfTypes(KotlinModule.class));
|
||||
}
|
||||
|
||||
static class MyDateFormat extends SimpleDateFormat {
|
||||
|
||||
MyDateFormat() {
|
||||
|
||||
Reference in New Issue
Block a user