
com.github.anonymousmister.bootfastconfig.jackson.AnnotationJackson Maven / Gradle / Ivy
package com.github.anonymousmister.bootfastconfig.jackson;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.github.anonymousmister.bootfastconfig.expand.AnnotationJson;
import com.fasterxml.jackson.core.Version;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.github.anonymousmister.bootfastconfig.constant.BeanNameConstant.ANNOTATION_JACKSON;
/**
* @author admin
* jackson 定制字段注解查找器
* {@link AnnotationJson extends Annotation>}
* 这个处理器会在 Controller 返回 被@ResponseBody 注释过的
* 方法返回实体类,里有被 extends Annotation> 注释过的字段
* 则会命中对应
* {@link AnnotationJson extends Annotation>}
* 的实现类 处理
*
*
* 由Jackson处理
*
*
* 支持:
* 序列化 会调用
*/
@Configuration(ANNOTATION_JACKSON)
public class AnnotationJackson extends Module implements ApplicationContextAware {
public final static String ARTIFACT_ID = "jackson-AnnotationJackson";
public final static Version VERSION = new Version(1, 0, 0, null, null, null);
private Map sysAnnotationJson;
@Override
public String getModuleName() {
return ARTIFACT_ID;
}
@Override
public Version version() {
return VERSION;
}
@Override
public void setupModule(SetupContext context) {
context.addBeanSerializerModifier(new BeanSerializerModifierAnnotation());
context.addBeanDeserializerModifier(new BeanDeserializerModifierAnnotation());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map beansOfType = applicationContext.getBeansOfType(AnnotationJson.class);
sysAnnotationJson = new HashMap<>(16);
beansOfType.values().stream().forEach(o -> sysAnnotationJson.put(o.getAnnotationClass(), o));
}
public class BeanDeserializerModifierAnnotation extends BeanDeserializerModifier {
@Override
public BeanDeserializerBuilder updateBuilder(final DeserializationConfig config,
final BeanDescription beanDesc,
final BeanDeserializerBuilder builder) {
Iterator beanPropertyIterator = builder.getProperties();
beanPropertyIterator.forEachRemaining(settableBeanProperty -> {
if (settableBeanProperty.getMember() == null) return;
if (settableBeanProperty.getMember().getAllAnnotations() == null) return;
final Iterable allAnnotations = settableBeanProperty.getMember().getAllAnnotations().annotations();
if (allAnnotations == null) return;
final Iterator iterator = allAnnotations.iterator();
while (iterator.hasNext()) {
final Annotation annotation = iterator.next();
final AnnotationJson annotationJson = sysAnnotationJson.get(annotation.annotationType());
if (annotationJson != null) {
annotationJson.updateBuilder(config, beanDesc, builder, settableBeanProperty, annotation);
}
}
});
return builder;
}
}
public class BeanSerializerModifierAnnotation extends BeanSerializerModifier {
@Override
public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) {
return beanProperties.stream().map(writer -> {
if (writer == null
&& writer.getMember() == null
&& writer.getMember().getAllAnnotations() == null &&
writer.getMember().getAllAnnotations().annotations() == null) return writer;
final Iterator annotations = writer.getMember().getAllAnnotations().annotations().iterator();
if (annotations == null) return writer;
while (annotations.hasNext()) {
final Annotation annotation = annotations.next();
final AnnotationJson annotationJson = sysAnnotationJson.get(annotation.annotationType());
if (annotationJson != null) {
annotationJson.changeProperties(config, beanDesc, beanProperties, writer, annotation);
}
}
return writer;
}).collect(Collectors.toList());
}
}
}