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对象也是安全的。
分享到:
相关推荐
Android Data Binding库是Google推出的一种强大的MVVM(Model-View-ViewModel)架构支持技术,它旨在简化Android应用中的UI逻辑,提高代码可读性和可维护性。本教程将深入探讨如何将Data Binding与RecyclerView结合...
Data Binding with Windows Forms 2.0: Programming Smart Client Data Applications with .NET By Brian Noyes ............................................... Publisher: Addison Wesley ...
**Android Data Binding 框架详解与实战演示** 在Android应用开发中,数据绑定是一种将UI组件和数据源紧密关联的技术,它可以帮助开发者减少在Activity或Fragment中的样板代码,提高代码可读性和维护性。本实战项目...
Android Data Binding是Google推出的一种强大的数据绑定库,它旨在简化Android应用中的UI逻辑,通过将数据绑定到XML布局文件中,使代码更加清晰、可读性更强,同时也减少了Activity或Fragment中的样板代码。...
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...
《AdventureWorks 数据绑定示例详解...总之,AdventureWorks Data Binding sample是VB.NET开发者学习数据绑定技术的一个宝贵资源,它通过实际操作展示了数据绑定的各个方面,有助于提升开发者构建数据驱动应用的能力。
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 ...
4. **Binding Context**:Binding Context是整个应用程序的上下文,它包含所有Binding Containers和Data Controls的信息。Binding Context提供了一个全局视图,使得在多个界面间共享数据和资源成为可能。 一个典型...
Flex Data Binding是Adobe Flex框架中的核心特性之一,它允许开发者创建数据驱动的应用程序,通过将UI组件的属性与数据模型的属性直接关联,实现实时的数据同步。在Flex中,数据绑定确保当数据源发生变化时,相关的...
在使用Android Data Binding时,有时会遇到在library module中出现错误的情况。这通常是由于Data Binding在编译过程中生成的binding类与library module的特定规则不兼容导致的。本文将深入探讨这个问题并提供解决...
这个压缩包"AndroidDataBindingExample, Android Data Binding 代码实战.zip"提供了一个实际的项目案例,帮助我们深入理解如何在实际开发中应用Android Data Binding。 1. **数据绑定的基本概念**: - 数据绑定...
在Android开发中,数据绑定(Data Binding)是一个强大的框架,它允许开发者更加直观地将UI组件与业务数据关联起来,从而简化代码并提高可维护性。这个Demo程序旨在展示数据绑定和事件绑定的基本用法,帮助开发者...
在安卓应用开发中,构建可交互的用户界面是至关重要的,而Data Binding库与RecyclerView的结合使用能够有效地提高代码的可读性和维护性,同时实现复杂的列表展示,如本示例中的三级列表。本文将详细解析如何利用Data...
3.2 Full Data Binding 用于json和Java Bean的相互转换。 下面从使用的角度上比较三种处理方式: Streaming API 执行效率最高,读写速度最快,另外两种方式都基于它实现; Tree Model 是最灵活的; Data ...
在本篇文章中,我们将深入探讨如何使用`BindingSource`来实现数据同步,以及其在实际应用中的工作原理。 首先,`BindingSource`组件的主要功能是作为数据源和控件之间的中间层,它能够帮助我们轻松地将控件的数据...
在IT行业中,数据绑定(Data Binding)和显式事务(Explicit Transactions)是两个非常关键的概念,尤其是在处理数据存储和更新时。这篇博文“Data Binding and Explicit Transactions”将深入探讨这两个主题,帮助...
《Data Binding with Windows Forms 2.0:编程智能客户端数据应用程序与.NET》是一本深入探讨.NET框架下Windows Forms 2.0数据绑定技术的专业书籍。数据绑定是将用户界面(UI)组件与数据源连接的过程,它使得应用...
这一特性是基于 Android 的 Data Binding 概念,并被华为的 HarmonyOS 移植和优化。 `HarmonyOS`,全称为 `OpenHarmony`,是一个开源的操作系统项目,旨在为多种智能设备提供统一的操作平台。`OpenHarmony` 提供了...
Android Data Binding Library 官方文档中文翻译,出自https://blog.csdn.net/jjwwmlp456/article/details/54915981的博客,被我制作成离线版pdf以供保存, Google官方文档地址:...