Data Binding第二种应用是Full Data Binding.也就是可以支持自定义的Java类到JSON对象的互相转换。
下面的代码演示了简单的使用方法:
类Response的定义:
import lombok.Getter;
import lombok.Setter;
/**
*
* @author chenshu
*/
public class Response {
@Getter @Setter
private String status;
@Getter @Setter
private String message;
}
调用代码:
public class App {
public static void main( String[] args ) throws IOException {
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
String jsonSource = "{\"message\":\"Login succeeded!\",\"status\":null}";
Response response = mapper.readValue(jsonSource, Response.class);
String result = mapper.writeValueAsString(response);
}
}
先通过命令mvn dependency:sources获取源代码。然后就可以调试进入代码观察。
readValue方法内部代码如下:
@SuppressWarnings("unchecked")
public <T> T readValue(String content, Class<T> valueType)
throws IOException, JsonParseException, JsonMappingException
{
// !!! TODO
// _setupClassLoaderForDeserialization(valueType);
return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), _typeFactory.constructType(valueType));
}
_typeFactory.constructType(valueType)使用参数Response.class创建一个SimpleType对象(JavaType的子类),创建时有一个LinkedHashMap对象做的缓存,如果已经创建过,则不再重复创建,取出来直接使用,因此还用到了多线程锁。参考TypeFactory.java里面的代码:
/**
* @param context Mapping of formal parameter declarations (for generic
* types) into actual types
*/
protected JavaType _fromClass(Class<?> clz, TypeBindings context)
{
// Very first thing: small set of core types we know well:
if (clz == String.class) return CORE_TYPE_STRING;
if (clz == Boolean.TYPE) return CORE_TYPE_BOOL;
if (clz == Integer.TYPE) return CORE_TYPE_INT;
if (clz == Long.TYPE) return CORE_TYPE_LONG;
// Barring that, we may have recently constructed an instance:
ClassKey key = new ClassKey(clz);
JavaType result;
synchronized (_typeCache) {
result = _typeCache.get(key);
}
if (result != null) {
return result;
}
// If context was needed, weed do:
/*
if (context == null) {
context = new TypeBindings(this, cls);
}
*/
// First: do we have an array type?
if (clz.isArray()) {
result = ArrayType.construct(_constructType(clz.getComponentType(), null), null, null);
/* Also: although enums can also be fully resolved, there's little
* point in doing so (T extends Enum<T>) etc.
*/
} else if (clz.isEnum()) {
result = new SimpleType(clz);
/* Maps and Collections aren't quite as hot; problem is, due
* to type erasure we often do not know typing and can only assume
* base Object.
*/
} else if (Map.class.isAssignableFrom(clz)) {
result = _mapType(clz);
} else if (Collection.class.isAssignableFrom(clz)) {
result = _collectionType(clz);
} else {
result = new SimpleType(clz);
}
synchronized (_typeCache) {
_typeCache.put(key, result);
}
return result;
}
我没有进一步跟踪,但是推测后面将利用Response.class.getMethods()获得并调用Response的setStatus和setMessage方法。
再看看调用代码:
return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), _typeFactory.constructType(valueType));
_jsonFactory.createJsonParser(content)创建了Jackson Streaming库里面的JsonParser对象。
_jsonFactory.createJsonParser(content)
下面代码来自于Streaming库的JsonFactory.java
/**
* Method for constructing parser for parsing
* contents of given String.
*/
public JsonParser createJsonParser(String content)
throws IOException, JsonParseException
{
Reader r = new StringReader(content);
// true -> we own the Reader (and must close); not a big deal
IOContext ctxt = _createContext(r, true);
// [JACKSON-512]: allow wrapping with InputDecorator
if (_inputDecorator != null) {
r = _inputDecorator.decorate(ctxt, r);
}
return _createJsonParser(r, ctxt);
}
这里只是大概了解一下用到了StringReader读取JSON字符串。因为属于Streaming库的内容,先放一放。
真正从JSON字符串读取对象需要用到叫做反序列化对象的东西,这个东西也是只创建一次,然后缓存。
ObjectMapper.java类里面的代码如下:
/**
* Method called to locate deserializer for the passed root-level value.
*/
protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext ctxt,
JavaType valueType)
throws JsonMappingException
{
// First: have we already seen it?
JsonDeserializer<Object> deser = _rootDeserializers.get(valueType);
if (deser != null) {
return deser;
}
// Nope: need to ask provider to resolve it
deser = ctxt.findRootValueDeserializer(valueType);
if (deser == null) { // can this happen?
throw new JsonMappingException("Can not find a deserializer for type "+valueType);
}
_rootDeserializers.put(valueType, deser);
return deser;
}
_rootDeserializers 变量类型是ConcurrentHashMap<JavaType, JsonDeserializer<Object>>,因此也是线程安全的。
结论:
1.每个自定义类型,都只会创建一个JavaType(其实是子类SimpleType),并缓存在LinkedHashMap变量中。该缓存变量位于ObjectMapper对象的TypeFactory变量中。
2.每个自定义类型都只有一个反序列化解析器,缓存在ConcurrentHashMap<JavaType, JsonDeserializer<Object>>变量中,该缓存变量是ObjectMapper的变量。
3.为了保证效率,要尽可能的只使用一个ObjectMapper对象。由于1和2的缓存读取和更新都是线程安全的,其他的代码也是线程安全,因此在多线程环境下使用一个ObjectMapper对象也是安全的。
分享到:
相关推荐
Data Binding with Windows Forms 2.0: Programming Smart Client Data Applications with .NET By Brian Noyes ............................................... Publisher: Addison Wesley ...
Android Data Binding结合RecyclerView的使用
This book is all about the what and the why of binding to data sources in a Windows Forms application built using Visual Studio 2005. The book goes into great detail in explaining the rationale behind...
These tutorials describe how to map your classes to your tables manually (rather than with an automated tool like SqlMetal) so that you can have support for M:M relationships and data binding against ...
Brian Noyes is a software architect, trainer, writer, and speaker with IDesign (www.idesign.net), a premier .NET architecture and design consulting and training company. He has been developing ...
豆瓣电影搜索 利用Data Binding在RecycleView展示电影列表
Data Binding with Windows Forms 2.0 Programming Smart Client Data Applications with .NET
Android Data Binding实战-入门篇学习笔记,包含实例代码。 基于 Android Studio平台。
3.2 Full Data Binding 用于json和Java Bean的相互转换。 下面从使用的角度上比较三种处理方式: Streaming API 执行效率最高,读写速度最快,另外两种方式都基于它实现; Tree Model 是最灵活的; Data ...
In this chapter, we examine data binding, the ability to associate non-GUI objects that hold and maintain data with the controls that present and receive that data
AndroidDataBindingExample, Android Data Binding 代码实战
In this chapter, we examine data binding, the ability to associate non-GUI objects that hold and maintain data with the controls that present and receive that data
主要介绍了C#应用BindingSource实现数据同步的方法,需要的朋友可以参考下
主要介绍了Android Data Binding 在 library module 中遇到错误及解决办法的相关资料,需要的朋友可以参考下
Android Data Binding Library 官方文档中文翻译,出自https://blog.csdn.net/jjwwmlp456/article/details/54915981的博客,被我制作成离线版pdf以供保存, Google官方文档地址:...
微软的示例! VB.net的 数据绑定!
Approaches and Best Practices in Web Service Style, Data Binding and Validation.pdf
主要介绍了Oracle ADF应用程序开发框架的数据绑定概念
Android Data Binding Adapter for ListView and RecyclerView..zip,使用新的android数据绑定框架将集合绑定到listviews和recyclerviews的简单方法
安卓-Data Binding+RecyclerView打造可以选择的三级列表 博客链接http://blog.csdn.net/Daxue_haha/article/details/77684085