Merge branch '1.5.x'

This commit is contained in:
Stephane Nicoll 2017-06-15 13:43:44 +02:00
commit eb30fe06ec
3 changed files with 59 additions and 20 deletions

View File

@ -41,6 +41,9 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
* {@link TomcatServletWebServerFactory} (unless you have defined your own * {@link TomcatServletWebServerFactory} (unless you have defined your own
* {@link ServletWebServerFactory} bean). * {@link ServletWebServerFactory} bean).
* <p> * <p>
* When using {@link SpringBootApplication}, the auto-configuration of the context is
* automatically enabled and adding this annotation has therefore no additional effect.
* <p>
* Auto-configuration tries to be as intelligent as possible and will back-away as you * Auto-configuration tries to be as intelligent as possible and will back-away as you
* define more of your own configuration. You can always manually {@link #exclude()} any * define more of your own configuration. You can always manually {@link #exclude()} any
* configuration that you never want to apply (use {@link #excludeName()} if you don't * configuration that you never want to apply (use {@link #excludeName()} if you don't
@ -48,11 +51,12 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
* {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied
* after user-defined beans have been registered. * after user-defined beans have been registered.
* <p> * <p>
* The package of the class that is annotated with {@code @EnableAutoConfiguration} has * The package of the class that is annotated with {@code @EnableAutoConfiguration},
* specific significance and is often used as a 'default'. For example, it will be used * usually via {@code @SpringBootApplication}, has specific significance and is often used
* when scanning for {@code @Entity} classes. It is generally recommended that you place * as a 'default'. For example, it will be used when scanning for {@code @Entity} classes.
* {@code @EnableAutoConfiguration} in a root package so that all sub-packages and classes * It is generally recommended that you place {@code @EnableAutoConfiguration} (if you're
* can be searched. * not using {@code @SpringBootApplication}) in a root package so that all sub-packages
* and classes can be searched.
* <p> * <p>
* Auto-configuration classes are regular Spring {@link Configuration} beans. They are * Auto-configuration classes are regular Spring {@link Configuration} beans. They are
* located using the {@link SpringFactoriesLoader} mechanism (keyed against this class). * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class).
@ -66,6 +70,7 @@ import org.springframework.core.io.support.SpringFactoriesLoader;
* @see ConditionalOnMissingBean * @see ConditionalOnMissingBean
* @see ConditionalOnClass * @see ConditionalOnClass
* @see AutoConfigureAfter * @see AutoConfigureAfter
* @see SpringBootApplication
*/ */
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.jackson; package org.springframework.boot.jackson;
import java.lang.reflect.Modifier;
import java.util.Map; import java.util.Map;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@ -78,8 +79,9 @@ public class JsonComponentModule extends SimpleModule implements BeanFactoryAwar
addDeserializerWithDeducedType((JsonDeserializer<?>) bean); addDeserializerWithDeducedType((JsonDeserializer<?>) bean);
} }
for (Class<?> innerClass : bean.getClass().getDeclaredClasses()) { for (Class<?> innerClass : bean.getClass().getDeclaredClasses()) {
if (JsonSerializer.class.isAssignableFrom(innerClass) if (!Modifier.isAbstract(innerClass.getModifiers()) &&
|| JsonDeserializer.class.isAssignableFrom(innerClass)) { (JsonSerializer.class.isAssignableFrom(innerClass)
|| JsonDeserializer.class.isAssignableFrom(innerClass))) {
try { try {
addJsonBean(innerClass.newInstance()); addJsonBean(innerClass.newInstance());
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.springframework.boot.jackson;
import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@ -31,34 +32,54 @@ import static org.assertj.core.api.Assertions.assertThat;
*/ */
public class JsonComponentModuleTests { public class JsonComponentModuleTests {
private AnnotationConfigApplicationContext context;
@After
public void closeContext() {
if (this.context != null) {
this.context.close();
}
}
@Test @Test
public void moduleShouldRegisterSerializers() throws Exception { public void moduleShouldRegisterSerializers() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( load(OnlySerializer.class);
JsonComponentModule.class, OnlySerializer.class); JsonComponentModule module = this.context.getBean(JsonComponentModule.class);
JsonComponentModule module = context.getBean(JsonComponentModule.class);
assertSerialize(module); assertSerialize(module);
context.close();
} }
@Test @Test
public void moduleShouldRegisterDeserializers() throws Exception { public void moduleShouldRegisterDeserializers() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( load(OnlyDeserializer.class);
JsonComponentModule.class, OnlyDeserializer.class); JsonComponentModule module = this.context.getBean(JsonComponentModule.class);
JsonComponentModule module = context.getBean(JsonComponentModule.class);
assertDeserialize(module); assertDeserialize(module);
context.close();
} }
@Test @Test
public void moduleShouldRegisterInnerClasses() throws Exception { public void moduleShouldRegisterInnerClasses() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( load(NameAndAgeJsonComponent.class);
JsonComponentModule.class, NameAndAgeJsonComponent.class); JsonComponentModule module = this.context.getBean(JsonComponentModule.class);
JsonComponentModule module = context.getBean(JsonComponentModule.class);
assertSerialize(module); assertSerialize(module);
assertDeserialize(module); assertDeserialize(module);
}
@Test
public void moduleShouldAllowInnerAbstractClasses() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
JsonComponentModule.class, ComponentWithInnerAbstractClass.class);
JsonComponentModule module = context.getBean(JsonComponentModule.class);
assertSerialize(module);
context.close(); context.close();
} }
private void load(Class<?>... configs) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(configs);
ctx.register(JsonComponentModule.class);
ctx.refresh();
this.context = ctx;
}
private void assertSerialize(Module module) throws Exception { private void assertSerialize(Module module) throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module); mapper.registerModule(module);
@ -85,4 +106,15 @@ public class JsonComponentModuleTests {
} }
@JsonComponent
static class ComponentWithInnerAbstractClass {
private static abstract class AbstractSerializer extends NameAndAgeJsonComponent.Serializer {
}
static class ConcreteSerializer extends AbstractSerializer {
}
}
} }