1.   概述

commons-beanutil开源库是apache组织的一个基础的开源库。为apache中很多类提供工具方法。学习它是学习其它开源库实现的基础。

Commons-beanutil中包括大量和JavaBean操作有关的工具方法,使用它能够轻松利用Java反射机制来完毕代码中所须要的功能,而不须要具体研究反射的原理和使用,同一时候,该类库中提出了动态Bean的概念,不但提供现有JavaBean的全部功能,并且还能够在执行时动态的对Bean中的属性数据类型进行改动以及增删属性。

本文研究的是v1.7版本号的commons-utils类库。

2.   转换器

2.1. 概述

转换器用来将输入数据转换成须要的数据类型。同一时候提供统一的接口,方便客户代码使用和扩展。

Commons-beanutils包中。全部转换器都从org.apache.commons.beanutils.Converter接口集成,加入自己须要的实现。

转换器分为下面三个部分:

l         数组转换器

l         普通转换器

l         地区敏感的转换器

l         转换器工具类

Converter子类包括的都是转换器的实现,普通情况下,不须要直接实例化这些类,仅仅须要使用ConvertUtil中convert方法,就能够进行数据类型的转换。

高级用户不但能够使用默认的转换方式,还能够向ConvertUtils中注冊新的或替代原有的转换器,实现须要的业务逻辑。

2.2.    转换器接口

转换器接口的具体信息例如以下:

类名

描写叙述

Converter

BeanUtil框架中使用的类型转换接口。能够将输入数据转换成须要的类型

2.3. 数组转换器

2.3.1.    概述

数组转换器的实现被封装在org.apache.commons.beanutils.converters包中。它的功能是将一定格式的输入字符串转换成不同类型的数组。输入数据以逗号分隔。开头和结尾能够用大括号括起来,比如:“{1, 2, 3, 4, 5}”。

全部数组转换器实现都从一个名为AbstractArrayConverter的抽象基类中集成,这个类提供了解析输入字符串的工具方法。

2.3.2.    类说明

数组转换器的具体类说明例如以下:

类名

描写叙述

AbstractArrayConverter

用来将输入字符串转换成数组的抽象类,提供了全部ArrayConverter须要的公共方法。

BooleanArrayConverter

将输入的不论什么对象转换成boolean数组,传入对象要满足下面几个条件后才干正确转换:

1.     传入对象为boolean数组,直接返回。

2.     传入对象为String数组。仅仅要数组中的每一个元素满足特定条件,就能够正常解析为boolean数组。

3.     传入对象为其它类型,仅仅要对象的toString()方法返回的字符串为逗号分隔的格式,而且每部分满足特定条件,就能够解析为boolean数组。

能够向boolean类型转换的字符串例如以下:

l         yes。y。true,on,1被转换为true

l         no。n。false,off。0被转换成false

l         其它字符串为非法字符串,假设遇到就停止转换,抛出异常或返回默认值。

原有代码实现的缺陷和改进方案:

1.     字符串数组解析算法反复:能够通过提取公共函数的方法消除反复。

2.     try/catch嵌套混乱:解决方法同上,仅仅要提取公共方法后自然就能够解决问题。

3.     特殊字符串被硬编码,比如yes。y。no,n等:将这些特殊字串提取成常量。放入映射表中维护,降低复杂的推断语句。

ByteArrayConverter

将传入对象转换为byte数组,假设转换失败,就抛出异常。

仍然有反复代码的问题。

CharacterArrayConverter

将对象转换为char数组

DoubleArrayConverter

将对象转换成double数组

FloatArrayConverter

将对象转换成float数组

IntegerArrayConverter

将对象转换成int数组

LongArrayConverter

将对象转换成long数组

ShortArrayConverter

将对象转换成short数组

StringArrayConverter

javadoc中说是将String数组转换成String数组。但不知道这样有什么意义。

查看代码后发现算法仅仅能转换int型的数组为String数组。其它的类型比方long型数组均不能正常转换。

最好不用这个类。

2.3.3.    类图

2.3.4.    小结

通过阅读数组转换器的代码,发现代码存在下面问题:

1.       代码冗余:代码不够简洁,每一个类中都或多或少的存在代码复制粘贴的痕迹。

2.       部分类的类型转换时存在缺陷,不能正常转换。

2.4.    普通转换器

2.4.1.    概述

普通转换器提供了将字符串转换成Java中的数字、时间日期类型和其它类型对象的方法。

普通转换器都直接从Converter接口集成,实现当中的抽象方法。

用户不但能够直接使用这些工具方法。也能够自己实现一些特殊业务需求的转换器。仅仅要实现Converter接口就可以。

2.4.2.    类说明

普通转换器的类说明例如以下:

类名

描写叙述

BigDecimalConverter

将字符串转换成BigDecimal类型数据。

转换失败时能够抛出异常,也能够返回默认值。

BigIntegerConverter

将数组转换成java.math.BigInteger类型对象,假设转换失败,能够抛出异常,也能够直接返回默认值。

BooleanConverter

将字符串转换成boolean类型对象。 假设转换失败,能够抛出异常。也能够返回默认值。

ByteConverter

将字符串转换成byte类型,假设转换失败。抛出异常或返回默认值。

CharacterConverter

将字符串转换成char,假设转换失败。抛出异常或返回默认值。

ClassConverter

从当前上下文的ClassLoader中载入类。假设类不存在。能够抛出异常,也能够直接返回默认值。

DoubleConverter

将输入字符串转换成double类型。假设转换失败,能够抛出异常。也能够返回默认值。

FileConverter

依据输入字符串初始化File对象,假设对象创建失败,抛出异常或返回默认值。

FloatConverter

将字符串转换成Float类型。假设转换失败,能够抛出异常,能够返回默认值。

IntegerConverter

将字符串转换成Integer类型对象。假设转换失败。能够抛出异常。也能够返回默认值。

LongConverter

将字符串转换成Long类型对象,假设转换失败,能够抛出异常,也能够返回默认值。

ShortConverter

将字符串转换成short类型对象,假设转换失败,能够抛出异常,也能够返回默认值。

SqlTimeConverter

将字符串转换成java.sql.Time对象,假设转换失败。能够抛出异常,也能够返回默认值。

SqlTimestampConverter

将字符串转换成javax.sql.Timestamp对象,假设转换失败,能够抛出异常。也能够返回默认值。

StringConverter

将字符串对象转换成字符串对象。

单独使用没有什么意义,可是在面向接口编程中实现了一种通用的转换方法。比較实用。

URLConverter

将字符串转换成URL对象。假设转换失败,抛出异常,或者直接返回默认值。

2.4.3.    类图

通用转换器的类结构图例如以下:

2.4.4.    小结

通用转换器存在的问题是:

对于默认值的校验不到位。没有针对详细Converter的类型进行校验,一旦转换失败,直接返回默认值后可能导致兴许代码出现ClassCastException。没有从源头杜绝这样的情况发生,尽管这样设计更加灵活,但弊大于利,最好是在类创建时进行校验。

2.5.    地区敏感转换器

2.5.1.    概述

地区敏感转换器都被封装在org.apache.commons.beanutils.locale和org.apache.commons.beanutils.locale.converters包中,前者提供一个集成自Converter的通用接口。后者提供这个接口的详细实现。

地区敏感转换器主要实现了当须要分地区进行转换时,须要进行的操作。主要功能是将带有不同地区特征的字符串转换成数字和时间日期类型对象。

2.5.2.    类说明

地区敏感转换器的类说明例如以下:

类名

描写叙述

LocaleConverter

进行地区敏感的数据类型的转换

BaseLocaleConverter

封装全部地区敏感conveter的公共方法

DateLocaleConverter

将地区敏感对象转换成java.util.Date对象。

SqlDateLocaleConverter

将输入对象转换成java.sql.Date 对象

SqlTimeLocaleConverter

将输入对象转换成java.sql.Time对象

SqlTimestampLocaleConverter

将输入对象转换成java.sql.Timestamp的格式

DecimalLocaleConverter

将地区敏感的输入转换成java.lang.Decimal对象

BigDecimalLocaleConverter

将输入的地区敏感字符串转换成java.math.BigDecimal对象。

没有重写不论什么方法。应该仅仅是为了和其它实现样式一致编写的方法。

BigIntegerLocaleConverter

将输入的地区敏感的对象转换成java.math.BigInteger 对象

没有重写不论什么方法,应该仅仅是为了和其它实现样式一致编写的方法。

ByteLocaleConverter

将输入的地区敏感的字符串转换成java.lang.Byte 对象

DoubleLocaleConverter

将地区敏感的对象转换成java.lang.Double对象

FloatLocaleConverter

将地区敏感的字符串转换成java.lang.Float对象

IntegerLocaleConverter

将地区敏感的字符串转换成java.lang.Integer对象

LongLocaleConverter

将地区敏感的字符串转换成java.lang.Long对象

ShortLocaleConverter

将地区敏感的字符串转换成java.lang.Short对象

StringLocaleConverter

将字符串转换成数字的字符串形式。

好像没有什么实际的作用

2.5.3.    类图

地区敏感转换器的类图例如以下:

2.5.4.    小结

地区敏感转换器中全部參数參数都是直接从构造函数中输入的,没有get和set,代码冗余度非常大,须要重构。

2.6.    转换器工具类

转换器相关的工具类是外界实际使用的接口。默认情况下,系统会向工具类中注冊上述各种类型数据的转换器对象,用户能够自己定义这些注冊信息。加入。改动或删除自己不须要的转换器。还能够将自己实现的类型注冊到转换器中。

转换器工具类的具体信息例如以下:

类名

描写叙述

ConvertUtils

将字符串对象转换成对应类型的对象。如。将String对象转换成Integer类型的对象,或将String对象转换成Integer数组对象。

默认使用系统自己定义的转换器,但接口开放。能够自己定义转换器进行数据类型转换。

ConvertUtilsBean

实际进行数据转换的类。

LocaleConvertUtils

和ConvertUtils作用类似。在转换的过程中依据不同的地区进行不用的转换。适用于地区敏感的数据。

LocaleConvertUtilsBean

2.7.    转换器总结

转换器这一套代码中实现了字符串向Java中各种数据类型的转换,这样在转换数据类型时不须要了解各种数据类型的转换API。仅仅须要知道Converter接口就可以。方便了开发者编写代码。

但这套代码也有非常多不足,当中最大的就是代码冗余的问题,小到函数内部的实现,大到整个的类结构,或多或少的都存在代码复制粘贴的影子,能够通过重构让代码变得更加清晰。

3.   动态bean

3.1. 概述

我们知道。每个JavaBean对象中包括一个Class对象,这个对象是单实例的而且在当前类载入器中全局唯一,由JVM维护。用来存储Bean中的属性描写叙述信息,这些信息在执行时无法改动。

动态bean符合JavaBean架构的基本思想,每个DynaBean实例有一个DynaClass对象。这个对象在同类DynaBean中唯一。但能够动态的对属性进行增删改的操作。这样就弥补了原来JavaBean架构中当Bean定义后不能对Bean中属性进行扩展的缺点。同一时候,提供了对bean中属性进行get/set的统一工具类,这些工具类的接口能够兼容动态Bean、标准Bean,以及映射(map)。

3.2. 动态Bean属性

动态Bean中的属性使用DynaProperty对象进行描写叙述,

类名

描写叙述

DynaProperty

动态bean中的属性,由属性名。属性类型两部分组成,对于数组、链表这类复杂类型,还增加了内容类型的概念,用来描写叙述这些复杂数据接口内部对象的类型。

3.3. 动态Bean的Class对象

3.3.1.    概述

动态Bean的Class对象描写叙述了Bean中包括的属性以及属性的数据类型,分为DynaClass和MutableDynaClass两个接口,当中MutableDynaClass接口继承自DynaClass接口。同一时候提供对Bean属性进行改动的方法。

具体描写叙述例如以下:

接口名

描写叙述

DynaClass

动态类模仿java.lang.Class 的实现。

使用DynaClass创建DynaBean 对象。全部DynaBean 对象共享一个DynaClass实例。

MutableDynaClass

对于DynaClass的特殊扩展,同意动态的加入和移除类的属性

3.3.2.    类说明

有多个类扩展了以上两个接口,具体信息例如以下:

类名

描写叙述

BasicDynaClass

对DynaClass接口的基本实现。提供了最主要的功能。

JDBCDynaClass

实现JDBC逻辑的动态类

ResultSetDynaClass

封装java.sql.ResultSet对象。提供和其它对象一样訪问方式的类。

RowSetDynaClass

从ResultSet中读取全部数据,封装在RowSetDynaBean中。

LazyDynaClass

DynaProperty

动态bean中的属性

WrapDynaClass

封装标准JavaBean的动态bean的DynaClass对象

3.3.3.    类图

上述类之间的关系例如以下:

3.4. 动态Bean

3.4.1.    概述

全部动态Bean实例都继承自DynaBean接口,能够创建DynaBean的实例,并对其属性进行改动。

接口具体信息例如以下:

接口名

描写叙述

DynaBean

提供了属性类型,名称。内容能够动态改动的JavaBean。

3.4.2.    类说明

下面类实现了DynaBean接口:

类名

描写叙述

WrapDynaClass

封装标准JavaBean的动态bean的DynaClass对象

BasicDynaBean

对DynaBean接口的最小实现

ResultSetIterator

封装ResultSetDynaClass的DynaBean

LazyDynaBean

能够动态加入属性的Bean

WrapDynaBean

封装标准的JavaBean。提供DynaBean的訪问方式

ConvertingWrapDynaBean

WrapDynaBean的子类。在set数据时能够提供必要的数据类型转换

3.4.3.    类图

4.   工具类

4.1. 概述

和不论什么成熟的开源包一样,commons-beanutils作为一个工具包,提供了对JavaBean以及动态Bean进行操作的工具类,即使没有使用动态Bean,仍然能够放心的使用这些工具类。

经常使用的工具类有下面几个部分:

l         PropertyUtils:对JavaBean中的属性值进行操作。

l         MethodUtils:使用反射的方式请求bean中的方法。

l         ConstructorUtils:使用反射的方式构造Bean的新实例。

l         BeanUtils:对JavaBean提供拷贝。赋值等操作。

l         LocaleBeanUtils:和BeanUtils功能类似,但还能够提供地区敏感数据的操作。

l         ContextClassLoaderLocal:为不同线程保存须要数据的工具类。

4.2. 具体说明

工具类的具体说明例如以下:

类名

描写叙述

ContextClassLoaderLocal

提供保存不同线程数据的工具类,在JDK1.5中已经能够用ThreadLocal取代.

PropertyUtils

使用Java反射API编写的工具类。用于方便的进行get和set。

本工具类的全部实现都是对PropertyUtilsBean的封装和代理。

PropertyUtilsBean

使用Java反射API进行set和get的工具类。

MethodUtils

封装以放射方式请求方法的工具方法

ConstructorUtils

使用反射方法请求构造函数创建新实例的工具类。能够简化程序中使用反射方式创建对象的代码。

BeanUtilsBean

提供对标准JavaBean和动态bean的操作。主要功能是复制bean中的内容,拷贝bean,为bean中的内容赋值和读取bean中内容。

BeanUtils

LocaleBeanUtils

和BeanUtils作用类似,但在运行对应方法时能够进行地区敏感数据的转换。

LocaleBeanUtilsBean

4.3. PropertyUtilsBean的方法

通过研读commons-beanutils的源码,整理了PropertyUtilsBean中的相关方法,例如以下所看到的:

PropertyUtilsBean的方法名

描写叙述

copyProperties

bean属性拷贝(copyProperties)。能够拷贝bean中全部属性,拷贝时遵循原来bean中的訪问控制策略:

l         动态bean向动态bean拷贝

l         动态bean向标准bean拷贝

l         MAP向动态bean拷贝

l         Map向标准bean拷贝

l         标准bean向动态bean拷贝

l         标准bean向标准bean拷贝

describe

将bean属性复制到Map中。

仅仅拷贝源bean中可读的属性,忽略其它属性。

getIndexedProperty

得到bean中的索引属性值:

有两种形式,一种的參数是string。还有一种的參数是属性名和位置。前者是“name[1]”的形式,后者是“name, 1”的形式。

比如。要取出bean中名为name属性的第2个对象,能够使用getIndexedProperty(bean, “name[1]”)的形式。也能够使用getIndexedProperty(bean, “name”, 1)的形式。

l         假设输入是动态bean。能够得到动态bean的索引属性。

假设属性是数组或列表,能够得到对应属性。

getMappedProperty

得到bean中的映射属性值:

本方法有两种原型。能够输入(bean, “name(key)”)取出bean中名为name映射属性中以key为键的属性值。也能够输入(bean, “name”, “key”)的方式取出bean中名为name映射属性中以key为键的属性值。

getNestedProperty

得到bean中的嵌套属性值。获取值的bean须要有get方法,还要有public訪问权限,否则BeanUtils中的类无法訪问。

适合在web页面上进行bean值的读取。

getPropertyDescriptor

得到bean中对应属性的属性描写叙述符

getPropertyDescriptors

得到bean中全部属性的属性描写叙述符

getPropertyEditorClass

得到bean中的属性编辑器类

getPropertyType

得到bean中对应属性类型

getReadMethod

得到属性描写叙述符中的get方法

getSimpleProperty

得到bean中简单属性的值

getWriteMethod

得到属性描写叙述符中的写方法

isReadable

推断bean中的指定属性是否可读

isWriteable

推断bean中的相应方法是否可写

setIndexedProperty

向bean中的索引属性赋值

setMappedProperty

向bean中的映射属性赋值

setNestedProperty

向bean中的内嵌属性赋值

setProperty

为bean中的属性赋值(包含简单属性和索引属性)

setSimpleProperty

为bean中的简单属性赋值

5.   总结

Commons-beanutils是一款优秀的工具类库。不但提供了一种能够动态扩展属性的JavaBean,同一时候封装了Java的反射机制。使用者能够更加easy的对反射进行操作,而不须要了解那么多和反射相关的知识。

转自:https://blog.csdn.net/weixin_34038652/article/details/85894505

java中commons-beanutils的介绍(转)的更多相关文章

  1. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  2. 史上最全 Java 中各种锁的介绍

    更多精彩原创内容请关注:JavaInterview,欢迎 star,支持鼓励以下作者,万分感谢. 锁的分类介绍 乐观锁与悲观锁 锁的一种宏观分类是乐观锁与悲观锁.乐观锁与悲观锁并不是特定的指哪个锁(J ...

  3. java中多线程入门有趣介绍

    我们在网上可以看到所有有关于java的线程的基本概念的很多解释,不乏有很多详细经典的解释和代码解说.但是我们的很多初学者看完不能有一个直观的印象,特别是一些没有编程基础的学习者,很多时候要花很多时间去 ...

  4. java中数据流的简单介绍

    java中的I/O操作主要是基于数据流进行操作的,数据流表示了字符或者字节的流动序列. java.io是数据流操作的主要软件包 java.nio是对块传输进行的支持 数据流基本概念 “流是磁盘或其它外 ...

  5. Java学习路线:Java中的位移运算符介绍

    学习java本来就是一件日积月累的事情,或许你通过自学能掌握一些皮毛技术,学到java的一些基本大面,但想要做到精通,还是需要自己技术的日积月累和工作经验的不断积累. 今天给大家分享的技术知识是:ja ...

  6. Java中系统属性Properties介绍 System.getProperty()参数大全

       在JDK文档中System类中有这样的方法getProperties()在此方法的详细介绍中有下面的参数可供使用: java.version Java 运行时环境版本 java.vendor J ...

  7. java中random()函数用法介绍

    Random() 创建一个新的随机数生成器.  代码如下 复制代码 Random(long seed) 使用单个 long 种子创建一个新的随机数生成器. 我们可以在构造Random对象的时候指定种子 ...

  8. Java中的单利模式介绍

    单利模式:本来是不准备写的,但是最近发现好多公司面试时都会或多或少的提到单利模式,因此今天把单利模式拉出来说说. 定义:只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且 ...

  9. Java中NIO的简单介绍

    NIO基本介绍 Java NIO(New IO) 也有人称之为Java non-blocking IO 是从Java1.4版本开始引入的一个新的IO API,可以代替标准的IO API.NIO与原来的 ...

  10. java中的ElasticSearch搜索引擎介绍。

    ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为Apach ...

随机推荐

  1. nginx+uwsgi02---django部署(推荐)

    参考  https://blog.csdn.net/weixin_39198406/article/details/79277580 https://www.cnblogs.com/alex3714/ ...

  2. Centos7查看关闭防火墙

    查看防火墙状态: firewall-cmd --state 关闭防火墙 service firewalld start 开机启动 service firewalld stop 禁止开机启动 syste ...

  3. 关于日志slf4j+logback&logback.xml配置

    1.maven依赖 <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <!-- <dependen ...

  4. Python实现八大排序(基数排序、归并排序、堆排序、简单选择排序、直接插入排序、希尔排序、快速排序、冒泡排序)

    目录 八大排序 基数排序 归并排序 堆排序 简单选择排序 直接插入排序 希尔排序 快速排序 冒泡排序 时间测试 八大排序 大概了解了一下八大排序,发现排序方法的难易程度相差很多,相应的,他们计算同一列 ...

  5. System.Data.EntityException: The underlying provider failed on Open.

    场景:IIS默认站点建立程序,使用Windows集成身份验证方式,连接SQLServer数据库也是采用集成身份验证.我报“System.Data.EntityException: The underl ...

  6. 怎样获取Cookie

    使用 document.cookie 获取; document.cookie

  7. C++string类字符串学习

    1.逆转字符串 第一种,使用algorithm中reverse函数. #include <algorithm> #include <string> #include <i ...

  8. SQL连接(join)

    INNER JOIN:如果表中有至少一个匹配,则返回行 LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行 RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行 FULL JOIN ...

  9. c# internal关键字

    对于一些大型的项目,通常由很多个DLL文件组成,引用了这些DLL,就能访问DLL里面的类和类里面的方法.比如,你写了一个记录日志的DLL,任何项目只要引用此DLL就能实现记录日志的功能,这个DLL文件 ...

  10. 处理python错误问题

    ------------恢复内容开始------------ 调试过程中遇到的问题 (1)爬取首页源码出现中文乱码 解决方案: 将网页编码强制转换成gbk,并去除解决乱码问题的三行代码. (2)程序运 ...