今天在写spring boot时,发现spring默认带的转json包为jackson,而一般都大家都会引入fastjson来替换。
引入fastjson的方式为,首先引入alibaba的fastjson包,然后在启动类中继承WebMvcConfigurerAdapter 重写 configureMessageConverters
@Override
public void configureMessageConverters(List> converters) {
super.configureMessageConverters(converters);
//1定义转换器 converter
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
//配置fastjson
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.PrettyFormat);
//将fastjson 传入转换器
converter.setFastJsonConfig(config);
//将converter添加到converters当中
converters.add(converter);
}
为什么spring这么成熟的框架用的jackson而我们却要改变为fastjson呢,难道fastjson真的就很fast?
我做了一个测试
//Spring 中默认用到的是Jackson 在框架搭建的时候一般都改用fastJson
public static void main(String [] str) {
Map map = new HashMap();
map = getMapData(map,1000000);
long fastJsonBegin = System.currentTimeMillis();
JSONObject fastJson = new JSONObject();
//fastJson
System.out.println("fastJson-------------------------------------------------");
// System.out.println("fastJson"+fastJson.toJSONString(map));
fastJson.toJSONString(map);
long fastJsonEnd = System.currentTimeMillis();
System.out.println("fastJson-------------time------------------------------------"+(fastJsonEnd-fastJsonBegin));
//jackson
long jacksonBegin = System.currentTimeMillis();
ObjectMapper jackson = new ObjectMapper();
try {
System.out.println("jackson-------------------------------------------------");
//System.out.println("jackson"+jackson.writeValueAsString(map));
jackson.writeValueAsString(map);
long jacksonEnd = System.currentTimeMillis();
System.out.println("jackson-------------time------------------------------------"+(jacksonEnd-jacksonBegin));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
public static Map getMapData(Map map,int count) {
for (int i = 0;i < count;i++) {
map.put("a"+i,i);
}
return map;
}
得到的运行结果
fastJson-------------------------------------------------
fastJson-------------time------------------------------------445
jackson-------------------------------------------------
jackson-------------time------------------------------------1123
果然是fastjson以快一倍的速度碾压,于是我对上面的代码进行了改动,将获取时间放在了创建fastjson及jackson的后面
//Spring 中默认用到的是Jackson 在框架搭建的时候一般都改用fastJson
public static void main(String [] str) {
Map map = new HashMap();
map = getMapData(map,1000000);
JSONObject fastJson = new JSONObject();
long fastJsonBegin = System.currentTimeMillis();
//fastJson
System.out.println("fastJson-------------------------------------------------");
// System.out.println("fastJson"+fastJson.toJSONString(map));
fastJson.toJSONString(map);
long fastJsonEnd = System.currentTimeMillis();
System.out.println("fastJson-------------time------------------------------------"+(fastJsonEnd-fastJsonBegin));
//jackson
ObjectMapper jackson = new ObjectMapper();
long jacksonBegin = System.currentTimeMillis();
try {
System.out.println("jackson-------------------------------------------------");
//System.out.println("jackson"+jackson.writeValueAsString(map));
jackson.writeValueAsString(map);
long jacksonEnd = System.currentTimeMillis();
System.out.println("jackson-------------time------------------------------------"+(jacksonEnd-jacksonBegin));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
结果为
fastJson-------------------------------------------------
fastJson-------------time------------------------------------385
jackson-------------------------------------------------
jackson-------------time------------------------------------309
很明显jackson的速度优于fastjson,只是,在创建对象时fastjson比jactson快
我们看一下两个的构造方法
fastjson
private static final long serialVersionUID = 1L;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private final Map map;
public JSONObject(){
this(DEFAULT_INITIAL_CAPACITY, false);
}
public JSONObject(int initialCapacity, boolean ordered){
if (ordered) {
map = new LinkedHashMap(initialCapacity);
} else {
map = new HashMap(initialCapacity);
}
}
jackson
public ObjectMapper() {
this(null, null, null);
}
public ObjectMapper(JsonFactory jf,
DefaultSerializerProvider sp, DefaultDeserializationContext dc)
{
/* 02-Mar-2009, tatu: Important: we MUST default to using
* the mapping factory, otherwise tree serialization will
* have problems with POJONodes.
* 03-Jan-2010, tatu: and obviously we also must pass 'this',
* to create actual linking.
*/
if (jf == null) {
_jsonFactory = new MappingJsonFactory(this);
} else {
_jsonFactory = jf;
if (jf.getCodec() == null) { // as per [JACKSON-741]
_jsonFactory.setCodec(this);
}
}
_subtypeResolver = new StdSubtypeResolver();
RootNameLookup rootNames = new RootNameLookup();
// and default type factory is shared one
_typeFactory = TypeFactory.defaultInstance();
SimpleMixInResolver mixins = new SimpleMixInResolver(null);
_mixIns = mixins;
BaseSettings base = DEFAULT_BASE.withClassIntrospector(defaultClassIntrospector());
_configOverrides = new ConfigOverrides();
_serializationConfig = new SerializationConfig(base,
_subtypeResolver, mixins, rootNames, _configOverrides);
_deserializationConfig = new DeserializationConfig(base,
_subtypeResolver, mixins, rootNames, _configOverrides);
// Some overrides we may need
final boolean needOrder = _jsonFactory.requiresPropertyOrdering();
if (needOrder ^ _serializationConfig.isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)) {
configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, needOrder);
}
_serializerProvider = (sp == null) ? new DefaultSerializerProvider.Impl() : sp;
_deserializationContext = (dc == null) ?
new DefaultDeserializationContext.Impl(BeanDeserializerFactory.instance) : dc;
// Default serializer factory is stateless, can just assign
_serializerFactory = BeanSerializerFactory.instance;
}
这样就一目了然的看到了耗时的原因