提交 25bb58a1 编写于 作者: T Tadaya Tsuyukubo 提交者: Sebastien Deleuze

Add shortcuts for Jackson mix-in annotations registration

This commit adds support for direct Jackson mix-in annotations registration in
Jackson2ObjectMapperFactoryBean and Jackson2ObjectMapperBuilder.

Issue: SPR-12144
上级 5a631177
...@@ -60,6 +60,7 @@ import org.springframework.util.ClassUtils; ...@@ -60,6 +60,7 @@ import org.springframework.util.ClassUtils;
* *
* @author Sebastien Deleuze * @author Sebastien Deleuze
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Tadaya Tsuyukubo
* @since 4.1.1 * @since 4.1.1
* @see #build() * @see #build()
* @see #configure(ObjectMapper) * @see #configure(ObjectMapper)
...@@ -81,6 +82,8 @@ public class Jackson2ObjectMapperBuilder { ...@@ -81,6 +82,8 @@ public class Jackson2ObjectMapperBuilder {
private final Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<Class<?>, JsonDeserializer<?>>(); private final Map<Class<?>, JsonDeserializer<?>> deserializers = new LinkedHashMap<Class<?>, JsonDeserializer<?>>();
private final Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
private final Map<Object, Boolean> features = new HashMap<Object, Boolean>(); private final Map<Object, Boolean> features = new HashMap<Object, Boolean>();
private List<Module> modules; private List<Module> modules;
...@@ -190,6 +193,21 @@ public class Jackson2ObjectMapperBuilder { ...@@ -190,6 +193,21 @@ public class Jackson2ObjectMapperBuilder {
return this; return this;
} }
/**
* Add mix-in annotations to use for augmenting specified class or interface.
* @param mixIns Map of entries with target classes (or interface) whose annotations
* to effectively override as key and mix-in classes (or interface) whose
* annotations are to be "added" to target's annotations as value.
* @since 4.1.2
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class)
*/
public Jackson2ObjectMapperBuilder mixIns(Map<Class<?>, Class<?>> mixIns) {
if (mixIns != null) {
this.mixIns.putAll(mixIns);
}
return this;
}
/** /**
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
*/ */
...@@ -414,6 +432,9 @@ public class Jackson2ObjectMapperBuilder { ...@@ -414,6 +432,9 @@ public class Jackson2ObjectMapperBuilder {
if (this.propertyNamingStrategy != null) { if (this.propertyNamingStrategy != null) {
objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy); objectMapper.setPropertyNamingStrategy(this.propertyNamingStrategy);
} }
for (Class<?> target : this.mixIns.keySet()) {
objectMapper.addMixInAnnotations(target, this.mixIns.get(target));
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
......
...@@ -118,6 +118,7 @@ import org.springframework.beans.factory.InitializingBean; ...@@ -118,6 +118,7 @@ import org.springframework.beans.factory.InitializingBean;
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Brian Clozel * @author Brian Clozel
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Tadaya Tsuyukubo
* @since 3.2 * @since 3.2
*/ */
public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean { public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper>, BeanClassLoaderAware, InitializingBean {
...@@ -213,6 +214,18 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper ...@@ -213,6 +214,18 @@ public class Jackson2ObjectMapperFactoryBean implements FactoryBean<ObjectMapper
this.builder.deserializersByType(deserializers); this.builder.deserializersByType(deserializers);
} }
/**
* Add mix-in annotations to use for augmenting specified class or interface.
* @param mixIns Map of entries with target classes (or interface) whose annotations
* to effectively override as key and mix-in classes (or interface) whose
* annotations are to be "added" to target's annotations as value.
* @since 4.1.2
* @see com.fasterxml.jackson.databind.ObjectMapper#addMixInAnnotations(Class, Class)
*/
public void setMixIns(Map<Class<?>, Class<?>> mixIns) {
this.builder.mixIns(mixIns);
}
/** /**
* Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option. * Shortcut for {@link MapperFeature#AUTO_DETECT_FIELDS} option.
*/ */
......
...@@ -190,6 +190,19 @@ public class Jackson2ObjectMapperBuilderTests { ...@@ -190,6 +190,19 @@ public class Jackson2ObjectMapperBuilderTests {
assertSame(strategy, objectMapper.getDeserializationConfig().getPropertyNamingStrategy()); assertSame(strategy, objectMapper.getDeserializationConfig().getPropertyNamingStrategy());
} }
@Test
public void mixIns() {
Class<?> target = String.class;
Class<?> mixinSource = Object.class;
Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
mixIns.put(target, mixinSource);
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().mixIns(mixIns).build();
assertEquals(1, objectMapper.mixInCount());
assertSame(mixinSource, objectMapper.findMixInClassFor(target));
}
@Test @Test
public void completeSetup() { public void completeSetup() {
NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance; NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;
......
...@@ -207,6 +207,21 @@ public class Jackson2ObjectMapperFactoryBeanTests { ...@@ -207,6 +207,21 @@ public class Jackson2ObjectMapperFactoryBeanTests {
assertSame(strategy, this.factory.getObject().getDeserializationConfig().getPropertyNamingStrategy()); assertSame(strategy, this.factory.getObject().getDeserializationConfig().getPropertyNamingStrategy());
} }
@Test
public void setMixIns() {
Class<?> target = String.class;
Class<?> mixinSource = Object.class;
Map<Class<?>, Class<?>> mixIns = new HashMap<Class<?>, Class<?>>();
mixIns.put(target, mixinSource);
this.factory.setMixIns(mixIns);
this.factory.afterPropertiesSet();
ObjectMapper objectMapper = this.factory.getObject();
assertEquals(1, objectMapper.mixInCount());
assertSame(mixinSource, objectMapper.findMixInClassFor(target));
}
@Test @Test
public void completeSetup() { public void completeSetup() {
NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance; NopAnnotationIntrospector annotationIntrospector = NopAnnotationIntrospector.instance;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册