General Utilizes

优质
小牛编辑
130浏览
2023-12-01

1. Overview

Apache Commons, Google Guava,Spring, 各家工具类各有所长,没有一种可以一统天下。尽量从三家中选择一个最好的,如果没有,就参考三家的代码自己编写。

1.1 String

Apache Commons的StringUtils有三家最全面的NullSafe的String工具函数,另外Guava提供少量更高级的函数。

1.2 Collection

Guava的提供了collection初始化的简写法和一些扩展类型. Apache Commons Collections有点老了,尽量不再使用。SpringSide Core中封装了一个Collections3.

1.3 Reflection

三家的Reflections类都不够粗暴,不能完全无视private/protected修饰符强制访问。因此SpringSide Core自行编写了一个粗暴型的,聚合各家函数的Relections。

1.4 Assert防御式 编程

三家都有提供校验参数的防御式编程API,选用Apache Commons Lang的Validate。
一开始用的是Spring的Assert,但Assert很容易和junit的弄乱,而且校验函数没有返回输入参数的能力,而且出错信息也没有格式化字符串+自定义参数的能力, 而Guava的类名叫Preconditions太长太怪,所以最后选了Apache的。

1.5 IO

选用Apache Commons IO 因为它提供了Stream/Reader/Writer/String间操作的函数 和 文件目录操作的函数。 不用Guava是因为它那完全脱离Java IO之外的抽象有不少的学习成本,而且功能并不完整。

另外Spring提供了一个Resource的抽象,可以方便加载文件路径,Classpath路径和Web App内路径的内容。

1.6 Concurrency

JDK自带,还有SpringSide自己也写了个Threads。
可自定义Thread名称的ThreadFactory很重要,否则所有线程都叫做 pool-x-thread-y",很难分辨。Google的ThreadFactoryBuilder 和 Apache Commons Lang的BasicThreadFactory都可以用。

1.7 Exceptions

Springside-core自己感觉常用需求整理了Exceptions。

1.8 Encode

Apache Commons Encode提供正宗的Base64/Hex编码, Apache Commons Lang提供XML/HTML的编码,JDK提供URL的编码,在SpringSide Core中提供一个Encodes封装,以一个统一入口调用上述各家的能力。

1.9 Time

Joda-Time,无异议。

2. Apache Commons

2.1 Lang3 StringUtils

选型见1.1, 示例见showcase中的StringDemo

2.2 Lang3 Validate

选型见1.4, 示例见showcase中的ValiateDemo

2.3 IOUtils

选型见1.5, 示例见showcase中的IOUtilsDemo, 含File与stream,string,byte[]的各种操作, String,Stream,Reader/Writer之间的个总转换.

3. Google Guava

3.1 Collections

Guava提供一个比JDK7更舒服的Collection初始化函数,见showcase中的CollectionsDemo。 另外Guava提供了BiMap, MultiValueMap与Table三种高级的Map,见showcase中的AdvancedMapDemo。

3.2 String相关

选型见1.1, 示例见showcase中的StringDemo,提供高级的Splitter和Joiner,以及在表名,类名,变量名见转换的函数(eg. ORDER_ITME, OrderItem, orderItem.)

4. Spring

4.1 Resource

见选型1.5

4. SpringSide

4.1 Reflections

提供反射调用函数和getter/setter函数以及直接绕过getter/setter直接访问属性的能力。
无视private/protected/public修饰符的关键是Class.getDeclaredMethods()函数,它与Class.getMethods()比,能返回private的函数,但只能返回当前类的(不会继承于父类的函数一起返回),然后可以method.setAccessible(true)来强制转换,当然,这并不总是成功,因为SecurityManager有时候会干预。

提供反射获取Class声明中的泛型参数,例子是public UserDao extends HibernateDao,获得User.class.注意这个User是定义在父类旁边的,这也是Java泛型中唯一能反射获得Class的地方。

4.2 Collections3

因为JDK有Collections, Guava有Collections2,所以只好叫Collections3。

  • 从Collection中通过反射,取得元素的某个属性值,组成新的Map,List或者String。或者将Collection转为String,每个元素执行toString(),元素间用分割符或者用prefix,postfix.
  • Collection的加减运算,及isEmpty(),getFirst,getLast()这样的常用函数, 目标是不用再引入Apache Commons Collection。见Showcase中的CollectionsDemo。

4.3 Exceptions

  • unchecked(), 将CheckedException转化为RuntimeException的方法
  • getStackTraceAsString(), 将整个Exception Stack所有消息转化为一个String
  • isCausedBy(), 判断异常是否由某些底层异常引起

4.4 Threads

  • sleep函数,屏蔽了Checked的InterruptedException.
  • 仿照JDK的shutdown/shutdownNow中的注释,提供了一个有超时控制,而且先尝试shutdown,超时了再尝试shutdownNow的gracefulShutdown()函数以及直接调用shutdownNow()并等待结束。
  • 简化了Google ThreadFactoryBuilder的调用。
  • 还有一个NoExceptionWrapper,保证不会有Exception抛出到线程池的Runnable,防止用户没有捕捉异常导致中断了线程池中的线程。

4.5 Encodes

选型见上, 见SpringSide Core中Encodes的测试用例。

4.6 Identities

各种生成Id的函数,比如uuid(),randomLog(),randomBase62()

4.7 PropertiesLoader

Properties文件载入工具类. 仿造Spring编写,可载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的值,但以System的Property优先. Path可以是classpath,绝对路径file或者web-inf/

5. https://www.xnip.cn/doc/buxguacj

异构对象间的复制拷贝,详见https://www.xnip.cn/shouce/596/44976.html章节。