1.概要
コモンズ・beanutilオープンソースのライブラリは、組織のApacheのオープン・ソース・ライブラリーの基盤です。apacheの多くのクラスは、ツールのための方法を提供しています。これは、他のオープンソースのライブラリの実装を学ぶための学習の基礎となっています。
コモンズ-beanutil関連ツール及び方法JavaBeanの動作の多数が含まれ、それは容易に原理および特定の研究を使用することなく、関数内のコードを完了するために必要にJavaリフレクションを利用することができ、同じ時間を反映し、提案されたライブラリ豆ダイナミックコンセプト、既存のJavaBeanのすべての機能を提供し、変更や追加属性を実行時に動的ビーンは、データ型の属性ができないだけ。
本論文では、コモンズ-utilsのライブラリーのV1.7バージョンです。
2.コンバータ
2.1概要
変換器は、所望のデータ型に入力データを変換するために使用されます。同時に、クライアントコードを使用して拡張することは容易、統一されたインタフェースを提供します。
パッケージには、コモンズ-々BeanUtils。すべてのインターフェイスはorg.apache.commons.beanutils.Converterからコンバータを一体化している、彼らの必要性を実感参加しました。
コンバータは、次の3つの部分に分かれ:
Lアレイ振動子
L通常コンバータ
変換器の感知領域L
L変換ツール
コンバータサブクラスコンバータ含み、通常の状況下で、これらは直接インスタンス化のクラスにする必要はありませんされて実現し、唯一の変換ConvertUtilメソッドを使用する必要があり、データ型変換を行うことが可能です。
上級ユーザーは、デフォルトの変換方法を使用するだけでなく、新しいConvertUtilsに登録したり、オリジナルのコンバータ、ビジネス・ロジックを達成するための必要性を置き換えることができることができないだけ。
2.2。インターフェイスコンバータ
特定の情報、例えば、次の変換インタフェース:
クラス名 |
説明で |
コンバータ |
フレームワーク変換インタフェースで使用BeanUtil型。必要性の種類に入力データを変換することができます |
2.3。配列コンバータ
2.3.1概要
トランスデューサアレイの実装は、org.apache.commons.beanutils.convertersパッケージに封入されています。その関数は、配列の異なるタイプにフォーマットされた入力文字列を変換することです。入力データは、カンマで区切られています。最初と最後のブレースのような、使用することができる: "{1、2、3、4、5}"
すべてのコンバータこのクラスのAbstractArrayConverterと呼ばれる抽象基底クラスから集積されているアレイを実装ツールの入力文字列を解析する方法を提供します。
2.3.2。クラス説明
(詳細な説明)配列型変換器、例えば、以下
クラス名 |
説明で |
AbstractArrayConverter |
入力文字列の配列抽象クラスにArrayConverterのすべてのニーズのための一般的な方法を提供します。 |
BooleanArrayConverter |
どのようなオブジェクトには、いくつかの才能正しい変換した後、以下の条件を満たすように、ブール配列、入ってくるオブジェクトに入ります。 ブール値の配列への1入ってくるオブジェクトは、直接返します。 文字列配列2.着信オブジェクト。配列の各要素にのみ、特定の条件が満たされている中で、正しくブール配列に解決することが可能です。 3.着信オブジェクトの他のタイプは、オブジェクトのみのtoString()メソッドが戻るコンマ区切り形式の文字列、および各セクションを満たし、特定の条件であると、ブール配列を解決することが可能です。 文字列に変換することができ、例えば、boolean型以下: リットルはい。Y。真、上、1がtrueに変換され、 リットルがありません。n個。偽、オフ。0は偽に変換され、 L他の違法な文字列文字列は、変換を停止するために、その出会いを仮定し、デフォルト値に例外または戻りをスロー。
そして、元の欠陥コードを実装の開発: 1.分析的な文字配列を繰り返し:繰り返し共通機能を抽出する処理によって除去することができます。
2.のtry / catchの入れ子の混乱:上記の溶液、自然な公共を抽出するための唯一の方法は、問題を解決することができるようになります。 3.特別な文字列がハードコーディングされた、などなどそうです。Y。いいえ、Nなど:定数を抽出するためにこれらの特殊文字列。マッピングテーブルのメンテナンスに、推論文の複雑さを軽減。 |
ByteArrayConverter |
例外をスロー、変換が失敗したと仮定すると、バイト配列にオブジェクトが入ってきます。
コードを繰り返し質問がまだあります。
|
CharacterArrayConverter |
オブジェクトが文字列に変換されます。 |
DoubleArrayConverter |
二重の配列にオブジェクト |
FloatArrayConverter |
フロートの配列にオブジェクト |
IntegerArrayConverter |
int型配列にオブジェクト |
LongArrayConverter |
長い配列へのオブジェクト |
ShortArrayConverter |
ショートの配列にオブジェクト |
StringArrayConverter |
javadocツールは、文字列配列に文字列配列を変換することであると言います。しかし、私はポイントが何であるかを知りません。 コードのアルゴリズムを見た後に文字列配列にint配列を変換することしかできました。長い配列の他の例のタイプは、通常は変換できません。 このクラスでは最高ではありません。 |
2.3.3。図クラス
2.3.4。概要
コード変換器のアレイを読み取ることによって、コードは、次のような問題点を発見しました。
1.冗長コード:コードシンプルなことに、各クラスは、コードのコピーペーストの痕跡の存在下で、多かれ少なかれです。
2.場合、変換のクラスタイプの欠陥部ではなく、通常の変換。
2.4。通常のコンバータ
2.4.1概要
一般的なコンバータは、Java、方法日時と、オブジェクトの他のタイプの数に文字列を変換するために設けられています。
共通インタフェースコンバータは、抽象メソッドを実装する直接変換し、統合されています。
ユーザーは、直接これらのツールのメソッドを使用することはできません。私たちは、コンバータの彼らの特別なビジネスニーズを実現することができます。コンバータインタフェースを実現するためだけにすることができます。
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