最近项目中采用fastJson解决了自己的需求,因此,打算看看fastJson的实现。
直接跟代码。
1.fastJson进行object转json的程序入口
public static final String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out);
for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
serializer.config(feature, true);
}
serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
setFilter(serializer, filters);
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}
观察上述的代码,见名知意,我们先猜测filters其实是类似于web端的filter的机制的,观看SerializeFilter的设计图
目前跟踪就大概是这几个类,其中对应的几个方法如下:没有深入具体看每一个方法,但是可以根据名称大体明白是对属性,值以及转json前后的一些处理。这些均可供我们扩展
2.回归1中的主逻辑代码查看SerializerFeature,看这个可传入参数到底是个什么:com.alibaba.fastjson.serializer.SerializerFeature
我们发现其是一个枚举类
public enum SerializerFeature {
QuoteFieldNames,
/**
*
*/
UseSingleQuotes,
/**
*
*/
WriteMapNullValue,
/**
*
*/
WriteEnumUsingToString,
/**
*
*/
UseISO8601DateFormat,
/**
* @since 1.1
*/
WriteNullListAsEmpty,
/**
* @since 1.1
*/
WriteNullStringAsEmpty,
/**
* @since 1.1
*/
WriteNullNumberAsZero,
/**
* @since 1.1
*/
WriteNullBooleanAsFalse,
/**
* @since 1.1
*/
SkipTransientField,
/**
* @since 1.1
*/
SortField,
/**
* @since 1.1.1
*/
@Deprecated
WriteTabAsSpecial,
/**
* @since 1.1.2
*/
PrettyFormat,
/**
* @since 1.1.2
*/
WriteClassName,
/**
* @since 1.1.6
*/
DisableCircularReferenceDetect,
/**
* @since 1.1.9
*/
WriteSlashAsSpecial,
/**
* @since 1.1.10
*/
BrowserCompatible,
/**
* @since 1.1.14
*/
WriteDateUseDateFormat,
/**
* @since 1.1.15
*/
NotWriteRootClassName,
/**
* @since 1.1.19
*/
DisableCheckSpecialChar,
/**
* @since 1.1.35
*/
BeanToArray,
/**
* @since 1.1.37
*/
WriteNonStringKeyAsString,
/**
* @since 1.1.42
*/
NotWriteDefaultValue
;
private SerializerFeature(){
mask = (1 << ordinal());
}
private final int mask;
public final int getMask() {
return mask;
}
public static boolean isEnabled(int features, SerializerFeature feature) {
return (features & feature.getMask()) != 0;
}
public static boolean isEnabled(int features, int fieaturesB, SerializerFeature feature) {
int mask = feature.getMask();
return (features & mask) != 0 || (fieaturesB & mask) != 0;
}
public static int config(int features, SerializerFeature feature, boolean state) {
if (state) {
features |= feature.getMask();
} else {
features &= ~feature.getMask();
}
return features;
}
public static int of(SerializerFeature[] features) {
if (features == null) {
return 0;
}
int value = 0;
for (SerializerFeature feature: features) {
value |= feature.getMask();
}
return value;
}
}
见名知意猜测其是一些对不同值类型的策略处理。具体暂不研究,继续往下看1中主代码逻辑设置好所有的features进入到setFilter中
private static void setFilter(JSONSerializer serializer, SerializeFilter... filters) {
for (SerializeFilter filter : filters) {
setFilter(serializer, filter);
}
}
添加进入一个个filter集合进行处理,引入菜鸟的过滤器设计模式可供参考对比理解https://www.runoob.com/design-pattern/filter-pattern.html,我们再一个复杂的业务代码中其实可以参考这个设计模式,特别是需要对数据进行一步步处理的时候来设计,不要仅仅使用模板方法做。可以结合起来进行处理。
进入1中的重头戏serializer.write(object);这才是我们生成json的最终方法,前期的filters与features可以理解为配置下到时候需要用的处理环境。
public final void write(Object object) {
if (object == null) {
out.writeNull();
return;
}
Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz);
try {
writer.write(this, object, null, null, 0);
} catch (IOException e) {
throw new JSONException(e.getMessage(), e);
}
}
我们可以看到具体的write方法,与方法入口1相同均用final修饰,是作者硬规定的套路模板方法,不允许后来者肆意修改。提高执行效率。有兴趣可以百度。
到这一步之前与前边类似,我们可以看看com.alibaba.fastjson.serializer.SerializeWriter这个类的结构设计发现其为final类,
主要继承Writer类进行写的操作。
在write方法中发现ObjectSerializer 此类
均实现了此接口的write方法
Class<?> clazz = object.getClass();
ObjectSerializer writer = getObjectWriter(clazz);//获得对应obj的ObjectSerializer
在com.alibaba.fastjson.serializer.SerializeConfig类中找到此方法,根据名称发现其采用适配器模式来匹配到对应的类,代码里包含的instance又为工厂与单例的结合运用。此类中在static块中将所有的基本数据类型对应的java类的序列化与反序列化的细节实现。Map.class.isAssignableFrom(clazz)这种写法是为类关系推断,类似于obj instanceof Map 这种对象关系推断。
public ObjectSerializer getObjectWriter(Class<?> clazz) {
ObjectSerializer writer = get(clazz);
if (writer == null) {
try {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
if (!(o instanceof AutowiredObjectSerializer)) {
continue;
}
AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
for (Type forType : autowired.getAutowiredFor()) {
put(forType, autowired);
}
}
} catch (ClassCastException ex) {
// skip
}
writer = get(clazz);
}
if (writer == null) {
final ClassLoader classLoader = JSON.class.getClassLoader();
if (classLoader != Thread.currentThread().getContextClassLoader()) {
try {
for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
if (!(o instanceof AutowiredObjectSerializer)) {
continue;
}
AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
for (Type forType : autowired.getAutowiredFor()) {
put(forType, autowired);
}
}
} catch (ClassCastException ex) {
// skip
}
writer = get(clazz);
}
}
if (writer == null) {
if (Map.class.isAssignableFrom(clazz)) {
put(clazz, MapSerializer.instance);
} else if (List.class.isAssignableFrom(clazz)) {
put(clazz, ListSerializer.instance);
} else if (Collection.class.isAssignableFrom(clazz)) {
put(clazz, CollectionSerializer.instance);
} else if (Date.class.isAssignableFrom(clazz)) {
put(clazz, DateSerializer.instance);
} else if (JSONAware.class.isAssignableFrom(clazz)) {
put(clazz, JSONAwareSerializer.instance);
} else if (JSONSerializable.class.isAssignableFrom(clazz)) {
put(clazz, JSONSerializableSerializer.instance);
} else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
put(clazz, JSONStreamAwareSerializer.instance);
} else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) {
put(clazz, EnumSerializer.instance);
} else if (clazz.isArray()) {
Class<?> componentType = clazz.getComponentType();
ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
put(clazz, new ArraySerializer(componentType, compObjectSerializer));
} else if (Throwable.class.isAssignableFrom(clazz)) {
put(clazz, new ExceptionSerializer(clazz));
} else if (TimeZone.class.isAssignableFrom(clazz)) {
put(clazz, TimeZoneCodec.instance);
} else if (Appendable.class.isAssignableFrom(clazz)) {
put(clazz, AppendableSerializer.instance);
} else if (Charset.class.isAssignableFrom(clazz)) {
put(clazz, CharsetCodec.instance);
} else if (Enumeration.class.isAssignableFrom(clazz)) {
put(clazz, EnumerationSeriliazer.instance);
} else if (Calendar.class.isAssignableFrom(clazz)) {
put(clazz, CalendarCodec.instance);
} else if (Clob.class.isAssignableFrom(clazz)) {
put(clazz, ClobSeriliazer.instance);
} else {
boolean isCglibProxy = false;
boolean isJavassistProxy = false;
for (Class<?> item : clazz.getInterfaces()) {
if (item.getName().equals("net.sf.cglib.proxy.Factory")
|| item.getName().equals("org.springframework.cglib.proxy.Factory")) {
isCglibProxy = true;
break;
} else if (item.getName().equals("javassist.util.proxy.ProxyObject")) {
isJavassistProxy = true;
break;
}
}
if (isCglibProxy || isJavassistProxy) {
Class<?> superClazz = clazz.getSuperclass();
ObjectSerializer superWriter = getObjectWriter(superClazz);
put(clazz, superWriter);
return superWriter;
}
if (Proxy.isProxyClass(clazz)) {
put(clazz, createJavaBeanSerializer(clazz));
} else {
put(clazz, createJavaBeanSerializer(clazz));
}
}
writer = get(clazz);
}
return writer;
}
然后执行真正的write方法,
writer.write(this, object, null, null, 0);
查看一个常用的map类的write过程com.alibaba.fastjson.serializer.MapSerializer
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.getWriter();
if (object == null) {
out.writeNull();
return;
}
Map<?, ?> map = (Map<?, ?>) object;
// if (out.isEnabled(SerializerFeature.SortField)) {
// if ((!(map instanceof SortedMap)) && !(map instanceof LinkedHashMap)) {
// try {
// map = new TreeMap(map);
// } catch (Exception ex) {
// // skip
// }
// }
// }
if (serializer.containsReference(object)) {
serializer.writeReference(object);
return;
}
SerialContext parent = serializer.getContext();
serializer.setContext(parent, object, fieldName, 0);
try {
out.write('{');
serializer.incrementIndent();
Class<?> preClazz = null;
ObjectSerializer preWriter = null;
boolean first = true;
if (out.isEnabled(SerializerFeature.WriteClassName)) {
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
out.writeString(object.getClass().getName());
first = false;
}
for (Map.Entry entry : map.entrySet()) {
Object value = entry.getValue();
Object entryKey = entry.getKey();
{
List<PropertyPreFilter> preFilters = serializer.getPropertyPreFiltersDirect();
if (preFilters != null && preFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!FilterUtils.applyName(serializer, object, (String) entryKey)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!FilterUtils.applyName(serializer, object, strKey)) {
continue;
}
}
}
}
{
List<PropertyFilter> propertyFilters = serializer.getPropertyFiltersDirect();
if (propertyFilters != null && propertyFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!FilterUtils.apply(serializer, object, (String) entryKey, value)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!FilterUtils.apply(serializer, object, strKey, value)) {
continue;
}
}
}
}
{
List<NameFilter> nameFilters = serializer.getNameFiltersDirect();
if (nameFilters != null && nameFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
entryKey = FilterUtils.processKey(serializer, object, (String) entryKey, value);
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
entryKey = FilterUtils.processKey(serializer, object, strKey, value);
}
}
}
{
List<ValueFilter> valueFilters = serializer.getValueFiltersDirect();
if (valueFilters != null && valueFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
value = FilterUtils.processValue(serializer, object, (String) entryKey, value);
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
value = FilterUtils.processValue(serializer, object, strKey, value);
}
}
}
if (value == null) {
if (!serializer.isEnabled(SerializerFeature.WriteMapNullValue)) {
continue;
}
}
if (entryKey instanceof String) {
String key = (String) entryKey;
if (!first) {
out.write(',');
}
if (out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.println();
}
out.writeFieldName(key, true);
} else {
if (!first) {
out.write(',');
}
if (out.isEnabled(SerializerFeature.BrowserCompatible)
|| out.isEnabled(SerializerFeature.WriteNonStringKeyAsString)) {
String strEntryKey = JSON.toJSONString(entryKey);
serializer.write(strEntryKey);
} else {
serializer.write(entryKey);
}
out.write(':');
}
first = false;
if (value == null) {
out.writeNull();
continue;
}
Class<?> clazz = value.getClass();
if (clazz == preClazz) {
preWriter.write(serializer, value, entryKey, null, 0);
} else {
preClazz = clazz;
preWriter = serializer.getObjectWriter(clazz);
preWriter.write(serializer, value, entryKey, null, 0);
}
}
} finally {
serializer.setContext(parent);
}
serializer.decrementIdent();
if (out.isEnabled(SerializerFeature.PrettyFormat) && map.size() > 0) {
serializer.println();
}
out.write('}');
}
所有的内容都输入进了SerializeWriter类,进入了下边方法
public void write(char c) {
int newcount = count + 1;
if (newcount > buf.length) {
if (writer == null) {
expandCapacity(newcount);
} else {
flush();
newcount = 1;
}
}
buf[count] = c;
count = newcount;
}
我们看到了buf数组
回到入口方法
public static final String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) {
SerializeWriter out = new SerializeWriter();
try {
JSONSerializer serializer = new JSONSerializer(out);
for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
serializer.config(feature, true);
}
serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
setFilter(serializer, filters);
serializer.write(object);
return out.toString();
} finally {
out.close();
}
}
进入out.toString观看
public String toString() {
return new String(buf, 0, count);
}
指向了同一个buf数组,处理完成。
结束
大体流程如此,里边当然有许多优秀的细节由于技术功底问题没有看得到,哪里有理解的不对烦请大佬留言促进鄙人进步。
补充
着急下班撤退差点忘记将SerializerFeature与上边将的SerializerFilter的使用位置忘记将,直接进入上边的com.fastjson.serializer.MapSerializer的write方法中便可以发现其处理的过程
if (out.isEnabled(SerializerFeature.WriteClassName)) {
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
out.writeString(object.getClass().getName());
first = false;
}
List<PropertyFilter> propertyFilters = serializer.getPropertyFiltersDirect();
if (propertyFilters != null && propertyFilters.size() > 0) {
if (entryKey == null || entryKey instanceof String) {
if (!FilterUtils.apply(serializer, object, (String) entryKey, value)) {
continue;
}
} else if (entryKey.getClass().isPrimitive() || entryKey instanceof Number) {
String strKey = JSON.toJSONString(entryKey);
if (!FilterUtils.apply(serializer, object, strKey, value)) {
continue;
}
}
}
看这个apply出现了吧,进入观察
public static boolean apply(JSONSerializer serializer, Object object, String key, Object propertyValue) {
List<PropertyFilter> propertyFilters = serializer.getPropertyFiltersDirect();
if (propertyFilters == null) {
return true;
}
for (PropertyFilter propertyFilter : propertyFilters) {
if (!propertyFilter.apply(object, key, propertyValue)) {
return false;
}
}
return true;
}
因此我们可以在其中添加自己的值,属性处理逻辑来控制结果的生成