推荐几个开源类库,超好用,远离996!
扫描二维码
随时随地手机看文章
1. MapStruct
![推荐几个开源类库,超好用,远离996!](/images/21ic_nopic.gif)
DTO(Data Transfer Object):数据传输对象,Service 向外传输的对象。但是这种转换工作就像是小时候,老师罚我们抄写名人名言 100 遍一样,十分枯燥,还容易出错。像这样:
BO(Business Object):业务对象,由 Service 层输出的封装业务逻辑的对象。
public class CarMapper {
CarDto carDoToCarDto(Car car) {
CarDto carDto = new CarDto();
carDto.setCarId(car.getCarId());
carDto.setWheel(car.getWheel());
carDto.setCarType(car.getCarType());
carDto.setCarColor(car.getCarColor());
......
}
}
要是 Car 有几十个字段,像 Car 一样的又有几十个类,你可以想一下,这种繁琐程度。在 MapStruct 之前,我们都是通过 Apache 或者 Spring 的 BeanUtils 工具,去自动做这种事情。但是这类工具有两个问题:1.性能比较差性能差主要是 Apache 的 BeanUtils 这套东西,它每次都要针对字段,做是否可读写的检查,还要根据字段生成对应的 PropertyDescriptor。这些严重影响了它的性能,所以,在阿里 Java 手册里,也不推荐用它。Spring 的 BeanUtils,虽然精简了很多 Apache 的 BeanUtils 的读写检查以及对应的属性信息记录,但是它依然是通过反射调用,而且是大量反射调用。这种性能也不能令人满意。2.运行期做转换,出错就代表损失BeanUtils 这类工具,有个统一的名称,叫做 Java 对象映射框架。它们大部分的实现都是在运行期去执行代码,然后在 Java 对象之间去拷贝对应的值。运行期间做这种事儿,有个最大的问题——整个项目启动运行后,才能发现错误。比如,转换的时候,类型不一致导致报错。对于此种情况,咱们大家都知道,这事儿就像开业酬宾没搞好,变成了开业仇宾……如果能写完代码,编译的时候就发现问题,这种损失就可以避免了。MapStruct 的引入就是为了解决以上这两个问题。MapStruct 首先是个代码产生器,它是根据注解,去产生一个专门用来转换的工具类,这个工具类,就像我们自己写的 Java 类一样,可以直接被使用,这样就避免了反射。同时,它产生的转换类也特别简单,就是默认会在两个类型的 Java 对象之间,拷贝同名属性的值。如果有了配置,属性不同名也可以拷贝。所以它的性能很好。示例代码如下:@Mapper
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mapping(target = "seatCount", source = "numberOfSeats")
CarDto carBoToCarDto(Car car);
}
MapStruct由于是个代码产生器,就带来了个巨大的好处,就是这家伙是在编译阶段就会生成对应的类,所以,如果有了类似类型转换不过去的问题,直接就编译报错了,根本等不到运行才发现。这样的话,就不会造成什么损失,这真是件十分 Nice 的事情。代码库地址https://github.com/mapstruct/mapstruct2. Retrofit
![推荐几个开源类库,超好用,远离996!](/images/21ic_nopic.gif)
- 不是基于 Spring 的项目
- 需要经常访问大量的第三方 Http 服务
- 访问 Http 服务的模型通常是异步回调
URIBuilder uriBuilder = new URIBuilder(uriBase);
uriBuilder.setParameter("a", "valuea");
uriBuilder.setParameter("b", "valueb");
uriBuilder.setParameter("c", "valuec");
uriBuilder.setParameter("d", "valued");
uriBuilder.setParameter("e", "valuee");
uriBuilder.setParameter("f", "valuef");
uriBuilder.setParameter("g", "valueg");
uriBuilder.setParameter("h", "valueh");
uriBuilder.setParameter("i", "valuei");
...
2.异步回调需要自己搞异步回调这种模型不好处理,主要就是需要自己去搞线程池,还要对线程池管理,还要考虑出错的重试之类的容错问题,实在麻烦。所以,我们就需要一套能用法简单,不用我们一直搞拼接参数,自己搞线程管理就能完成对第三方 Http 服务访问的库。其实我们也想过用 Feign 这套框架的。但是,这套东西和 Spring 绑定的太紧了。如果离开 Spring,它的一些功能就没法简单的通过注解直接使用,必须自己写代码调用。而且,Feign 要实现异步回调方式使用,尤其在协程方面,还是需要自己开发。这时候,Retrofit 就跳进了我们的选型里。Retrofit 的模型里,异步回调模型它支持的很好,我们只需要实现一个 Callable 就够了。并且最清爽的是,它和 Spring 没什么关系。Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://xxx.example.com/")
.build();
public interface BlogService {
@GET("blog/{id}")
Call getBlog(@Path("id") int id) ;
}
BlogService service = retrofit.create(BlogService.class);
Call call = service.getBlog(2);
// 用法和OkHttp的call如出一辙,
// 回调
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
try {
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, Throwable t) {
t.printStackTrace();
}
});
你看,只需要写上这些代码,我们就不需要操心恼人的 Url 拼接和异步回调的管理问题了。全交给了 Retrofit,着实推荐。代码库地址https://github.com/square/retrofit3. Faker
![推荐几个开源类库,超好用,远离996!](/images/21ic_nopic.gif)
Faker faker = new Faker();
String name = faker.name().fullName(); // Miss Samanta Schmidt
String firstName = faker.name().firstName(); // Emory
String lastName = faker.name().lastName(); // Barton
String streetAddress = faker.address().streetAddress(); // 60018 Sawayn Brooks Suite 449
几行代码,我们需要的一个用户就有了。用上 Faker 后,小伙伴们纷纷表示“有更多的时间摸鱼了”。代码库地址https://github.com/DiUS/java-faker4. Wiremock
![推荐几个开源类库,超好用,远离996!](/images/21ic_nopic.gif)
WireMock.stubFor(get(urlPathMatching("/aliyun/.*"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", APPLICATION_JSON)
.withBody("\"testing-library\": \"WireMock\"")));
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(String.format("http://localhost:%s/aliyun/wiremock", port));
HttpResponse httpResponse = httpClient.execute(request);
String stringResponse = convertHttpResponseToString(httpResponse);
verify(getRequestedFor(urlEqualTo(ALIYUN_WIREMOCK_PATH)));
assertEquals(200, httpResponse.getStatusLine().getStatusCode());
assertEquals(APPLICATION_JSON, httpResponse.getFirstHeader("Content-Type").getValue());
assertEquals("\"testing-library\": \"WireMock\"", stringResponse);
代码库地址https://github.com/wiremock/wiremock结语
虽然 Java 有很多遭人诟病的地方,但是 Java 最重要的优点之一,就是它的生态,有其琳琅满目的各种工具类库。希望大家都“懒”一点,不要埋头去做无效的苦干,不要自己造轮子,你要相信:你遇到的问题,基本已经有很多人遇到过了,而且已经被牛人给解决了,把轮子都给你造好了。