diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java index 2f47ea7f7c5..bacc5cef1e7 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java @@ -54,6 +54,7 @@ public class CodecsAutoConfiguration { static class JacksonCodecConfiguration { @Bean + @Order(0) @ConditionalOnBean(ObjectMapper.class) public CodecCustomizer jacksonCodecCustomizer(ObjectMapper objectMapper) { return (configurer) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java index 1f813b80358..abe0bde6921 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java @@ -16,13 +16,17 @@ package org.springframework.boot.autoconfigure.http.codec; import java.lang.reflect.Method; +import java.util.List; +import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.http.HttpProperties; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.web.codec.CodecCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.http.codec.CodecConfigurer; import org.springframework.http.codec.support.DefaultClientCodecConfigurer; @@ -34,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link CodecsAutoConfiguration}. * * @author Madhura Bhave + * @author Andy Wilkinson */ public class CodecsAutoConfigurationTests { @@ -76,6 +81,30 @@ public class CodecsAutoConfigurationTests { }); } + @Test + public void jacksonCodecCustomizerBacksOffWhenThereIsNoObjectMapper() { + this.contextRunner.run((context) -> assertThat(context) + .doesNotHaveBean("jacksonCodecCustomizer")); + } + + @Test + public void jacksonCodecCustomizerIsAutoConfiguredWhenObjectMapperIsPresent() { + this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class) + .run((context) -> assertThat(context).hasBean("jacksonCodecCustomizer")); + } + + @Test + public void userProvidedCustomizerCanOverrideJacksonCodecCustomizer() { + this.contextRunner.withUserConfiguration(ObjectMapperConfiguration.class, + CodecCustomizerConfiguration.class).run((context) -> { + List codecCustomizers = context + .getBean(CodecCustomizers.class).codecCustomizers; + assertThat(codecCustomizers).hasSize(3); + assertThat(codecCustomizers.get(2)) + .isInstanceOf(TestCodecCustomizer.class); + }); + } + static class TestAnnotationAwareOrderComparator extends AnnotationAwareOrderComparator { @@ -86,4 +115,47 @@ public class CodecsAutoConfigurationTests { } + @Configuration + static class ObjectMapperConfiguration { + + @Bean + ObjectMapper objectMapper() { + return new ObjectMapper(); + } + + } + + @Configuration + static class CodecCustomizerConfiguration { + + @Bean + CodecCustomizer codecCustomizer() { + return new TestCodecCustomizer(); + } + + @Bean + CodecCustomizers codecCustomizers(List customizers) { + return new CodecCustomizers(customizers); + } + + } + + private static final class TestCodecCustomizer implements CodecCustomizer { + + @Override + public void customize(CodecConfigurer configurer) { + } + + } + + private static final class CodecCustomizers { + + private final List codecCustomizers; + + private CodecCustomizers(List codecCustomizers) { + this.codecCustomizers = codecCustomizers; + } + + } + }